【问题标题】:IllegalArgumentException: Cannot draw recycled bitmapsIllegalArgumentException:无法绘制回收的位图
【发布时间】:2013-09-10 04:00:57
【问题描述】:

所以我有一个ExpandableListView,在子视图中我有一个ListView。当我单击其中一个项目时,它会打开另一个活动。当我按下并单击另一个列表项时会出现问题。当我这样做时,我得到了提到的异常。我从不使用位图,所以我真的不知道是什么导致了问题,是重绘项目还是问题?

我读到(参考Caching Bitmaps)我应该实现一个缓存机制,但我不知道如何开始以及如果我不使用任何位图应该缓存什么?我在这里错过了什么?

Logcat:

09-10 05:48:03.345: E/AndroidRuntime(21011): FATAL EXCEPTION: main
09-10 05:48:03.345: E/AndroidRuntime(21011): java.lang.IllegalArgumentException: Cannot    draw recycled bitmaps
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.GLES20Canvas.drawBitmap(GLES20Canvas.java:789)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.GLES20RecordingCanvas.drawBitmap(GLES20RecordingCanvas.java:118)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:393)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.widget.ImageView.onDraw(ImageView.java:967)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.View.draw(View.java:13707)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.View.getDisplayList(View.java:12645)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.View.getDisplayList(View.java:12689)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.View.draw(View.java:13423)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.ViewGroup.drawChild(ViewGroup.java:2928)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.View.getDisplayList(View.java:12643)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.View.getDisplayList(View.java:12689)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.View.draw(View.java:13423)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.ViewGroup.drawChild(ViewGroup.java:2928)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.View.draw(View.java:13710)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.widget.FrameLayout.draw(FrameLayout.java:467)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.widget.ScrollView.draw(ScrollView.java:1576)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.View.getDisplayList(View.java:12645)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.View.getDisplayList(View.java:12689)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.View.draw(View.java:13423)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.ViewGroup.drawChild(ViewGroup.java:2928)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.View.draw(View.java:13710)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.widget.FrameLayout.draw(FrameLayout.java:467)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.widget.HorizontalScrollView.draw(HorizontalScrollView.java:1562)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.View.getDisplayList(View.java:12645)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.View.getDisplayList(View.java:12689)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.View.draw(View.java:13423)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.ViewGroup.drawChild(ViewGroup.java:2928)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.View.getDisplayList(View.java:12643)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.View.getDisplayList(View.java:12689)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.View.draw(View.java:13423)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.ViewGroup.drawChild(ViewGroup.java:2928)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.View.getDisplayList(View.java:12643)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.View.getDisplayList(View.java:12689)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.View.draw(View.java:13423)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.ViewGroup.drawChild(ViewGroup.java:2928)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.View.getDisplayList(View.java:12643)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.View.getDisplayList(View.java:12689)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.View.draw(View.java:13423)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.ViewGroup.drawChild(ViewGroup.java:2928)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2797)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.View.draw(View.java:13710)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.widget.FrameLayout.draw(FrameLayout.java:467)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2211)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.View.getDisplayList(View.java:12645)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.View.getDisplayList(View.java:12689)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.HardwareRenderer$GlRenderer.draw(HardwareRenderer.java:1198)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.ViewRootImpl.draw(ViewRootImpl.java:2173)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2045)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1854)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:989)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4351)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.Choreographer.doCallbacks(Choreographer.java:562)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.Choreographer.doFrame(Choreographer.java:532)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.os.Handler.handleCallback(Handler.java:725)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.os.Handler.dispatchMessage(Handler.java:92)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.os.Looper.loop(Looper.java:137)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at android.app.ActivityThread.main(ActivityThread.java:5191)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at java.lang.reflect.Method.invokeNative(Native Method)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at java.lang.reflect.Method.invoke(Method.java:511)
09-10 05:48:03.345: E/AndroidRuntime(21011):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
09-10 05:48:03.345: E/AndroidRuntime(21011):    a

代码:

我的可扩展列表适配器:

public class StaffExpandableListAdapter extends BaseExpandableListAdapter {

private ArrayList<StaffGroup> staffGroups;
private LayoutInflater layoutInflater;
private Resources resource;
private RoomAdapter ra;

private Context context;

public StaffExpandableListAdapter(Context context,
        ArrayList<StaffGroup> staffGroups) {
    this.staffGroups = staffGroups;
    this.layoutInflater = LayoutInflater.from(context);
    this.resource = context.getResources();
    this.ra = new RoomAdapter(context);

    this.context = context;
}

@Override
public Object getChild(int groupPosition, int childPosition) {
    StaffChild staffChild = staffGroups.get(groupPosition)
            .getStaffDetails();
    return staffChild;
}

@Override
public long getChildId(int groupPosition, int childPosition) {
    return childPosition;
}

@Override
public View getChildView(int groupPosition, int childPosition,
        boolean isLastChild, View convertView, ViewGroup parent) {
    final StaffChild staffChildInfo = (StaffChild) getChild(groupPosition,
            childPosition);
    ViewHolderChild holder;
    if (convertView == null) {
        convertView = layoutInflater
                .inflate(R.layout.child_row_staff, null);
        holder = new ViewHolderChild();
        holder.contact = (TextView) convertView
                .findViewById(R.id.tv_staff_contact);
        holder.consultation = (TextView) convertView
                .findViewById(R.id.tv_staff_consultation);
        holder.locations = (ListView) convertView
                .findViewById(R.id.lv_staff_locations);

        holder.noRoomLocation = (TextView) convertView.findViewById(R.id.no_room_location);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolderChild) convertView.getTag();

    }

    holder.contact.setText(staffChildInfo.getContact().trim());

    holder.consultation.setText(staffChildInfo.getConsultation().trim());
    String roomId = staffChildInfo.getRoomId();

    final ArrayList<RoomLocation> roomLocationInfos = new ArrayList<RoomLocation>();
    String[] roomIdForSearch = roomId.split(":");
    if (roomIdForSearch.length <= 1) {
        holder.noRoomLocation.setVisibility(View.VISIBLE);
        holder.locations.setVisibility(View.GONE);
    }else{
        holder.noRoomLocation.setVisibility(View.GONE);
        holder.locations.setVisibility(View.VISIBLE);

        for (int i = 1; i < roomIdForSearch.length; i++) {
            ra.openToRead();
            roomLocationInfos.add(ra.getRoomLocation(Integer
                    .valueOf(roomIdForSearch[i].trim())));
            ra.close();
        }

        String[] items = new String[roomLocationInfos.size()];
        int i = 0;
        for (RoomLocation rl : roomLocationInfos) {
            items[i++] = formatLocationName(rl.getName());

        }

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(context,
                R.layout.item_location, R.id.tv_item_location, items);
        holder.locations.setAdapter(adapter);
        adapter.notifyDataSetInvalidated();
        adapter.notifyDataSetChanged();
        Utility.setListViewHeightBasedOnChildren(holder.locations);

        holder.locations.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                startBuildnigPlanActivityInSearchMod(
                        roomLocationInfos.get(position).getX(),
                        roomLocationInfos.get(position).getY(),
                        roomLocationInfos.get(position).getBuildingId(),
                        roomLocationInfos.get(position).getFloorId());

            }

        });
        holder.locations.setFocusable(false);

    }

    return convertView;
}

@SuppressLint("DefaultLocale")
private String formatLocationName(String locationNumber) {
    String location1Format[] = locationNumber.split(":");
    String buildingName = location1Format[0].trim();
    String roomName = location1Format[1].trim();
    return roomName + " (" + buildingName.toUpperCase(Locale.getDefault())
            + ")";
}

@Override
public int getChildrenCount(int groupPosition) {
    return 1;
}

@Override
public Object getGroup(int groupPosition) {
    return staffGroups.get(groupPosition);
}

@Override
public int getGroupCount() {
    return staffGroups.size();
}

@Override
public long getGroupId(int groupPosition) {
    return groupPosition;
}

@Override
public View getGroupView(int groupPosition, boolean isExpanded,
        View convertView, ViewGroup parent) {
    StaffGroup staffGroupInfo = (StaffGroup) getGroup(groupPosition);

    ViewHolderGroup holder;
    if (convertView == null) {
        convertView = layoutInflater
                .inflate(R.layout.group_row_staff, null);
        holder = new ViewHolderGroup();
        holder.staffId = (TextView) convertView
                .findViewById(R.id.tv_staff_id);
        holder.staffName = (TextView) convertView
                .findViewById(R.id.tv_staff_name);
        holder.groupIndicator = (ImageView) convertView
                .findViewById(R.id.iv_group_indicator);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolderGroup) convertView.getTag();
    }

    if (isExpanded) {
        holder.groupIndicator.setImageDrawable(resource
                .getDrawable(R.drawable.iv_expanded));
    } else {
        holder.groupIndicator.setImageDrawable(resource
                .getDrawable(R.drawable.iv_not_expanded));
    }

    holder.staffId.setText(staffGroupInfo.getId().trim());
    if (staffGroupInfo.getTitle().trim().equals("No data")) {
        holder.staffName.setText(staffGroupInfo.getStaffName().trim());
    } else {
        holder.staffName.setText(staffGroupInfo.getStaffName().trim()
                + ", " + staffGroupInfo.getTitle().trim());
    }

    return convertView;

}

@Override
public boolean hasStableIds() {
    return true;
}

@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
    return true;
}

public void startBuildnigPlanActivityInSearchMod(){
    ...
}

/**
 * ViewHolderGroup class for group view
 * 
 * 
 * 
 */
static class ViewHolderGroup {
    TextView staffId;
    TextView staffName;
    ImageView groupIndicator;

}

/**
 * ViewHolderChild class for child view
 * 
 * 
 * 
 */
static class ViewHolderChild {
    ListView locations;
    TextView contact;
    TextView consultation;
    TextView noRoomLocation;
}

}

ListView 是在 getChildView 内部创建的,setOnItemClickListener 也是如此。在我的活动中,我通常调用ExpandableListView。希望这有帮助?!

【问题讨论】:

  • 你能把你的代码贴在这里吗?
  • 这是一个相当大的代码sn-p,我可以尝试只发布重要部分。您对代码的特定部分感兴趣吗?
  • 我觉得还有很多空间可以粘贴你的代码
  • 我只想查看您的列表适配器以及您使用它的位置的活动
  • 我为 GroupView 使用 ImageView groupIndicator。但我在我的其他 ExpandableListViews 中有这个,从来没有问题。我在 ListView 布局中使用了 ImageView,但我删除了它,我得到了同样的异常?

标签: android listview bitmap


【解决方案1】:

我认为您不再需要回答了,但我遇到了同样的问题,我找到了这个解决方案: 我正在使用这个功能:

Bitmap thumbnail = Bitmap.createScaledBitmap(bmp, w, h, true)
if (!bmp.isRecycled()) {
    bmp.recycle();
}
bmp = null;

通过阅读该方法的描述,我发现:

“在可能的情况下,从现有位图缩放创建一个新位图。 如果指定的宽高与源位图的当前宽高相同,则返回源位图,不返回 新位图已创建。”

所以基本上,在这种情况下,w 和 h 匹配我的“bmp”宽度和高度,因此 createScaledBitmap() 函数不会创建新对象,而是使用源对象 (bmp) 和“bmp”地址将用于我的“缩略图”变量。而如果我尝试回收bmp(认为它不会再被使用),我就错了,因为变量“thumbnail”仍然使用这个相同的地址,我的其余代码将无法工作。

所以这是我的简单解决方案:

Bitmap thumbnail = Bitmap.createScaledBitmap(bmp, w, h, true);
if (!thumbnail.equals(bmp)) {
    if (!bmp.isRecycled()) {
        bmp.recycle();
    }
    bmp = null;
}

希望这会对某人有所帮助!

【讨论】:

    【解决方案2】:

    试试这个:

    if (!bitmap.isRecycled())
               {
                 bitmap.recycle;
               }
    

    然后创建您的位图。

    【讨论】:

    • 但我不使用位图:/ 我错过了什么吗?
    • @Aksiom 你在 R.layout.child_row 中有一个 imageview 吗?还是图片按钮?
    • @user2045570 不,我没有。我有 6 个 TextViews 和 1 个 ListView 这就是我在该布局中使用的所有内容。
    猜你喜欢
    • 2013-08-31
    • 2015-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-07
    • 1970-01-01
    相关资源
    最近更新 更多