【问题标题】:Content of ListView takes to much memoryListView 的内容占用大量内存
【发布时间】:2011-09-01 07:11:59
【问题描述】:

ListView 包含相当多的项目(20 或更多),每个项目都是带有位图源的 ImageView。这些位图未压缩,大小约为 640x480。当 ListView 刚刚加载时,它会占用一些内存,但如果我滚动它,则可能会发生错误 "Memory exceed VM budjet"。当我用另一个片段替换片段时,ListView 仍然挂在内存中。如何清除 ram/ListView 缓存?

更新:

我使用SimpleCursorAdapterViewBinder

    SimpleCursorAdapter.ViewBinder viewBinder = new SimpleCursorAdapter.ViewBinder() {
        public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
            if (columnIndex == 0) {
                TextView tv1 = (TextView) view;
                if (cursor.getInt(4) == 0)
                    tv1.setTextColor(Color.GRAY);
                else
                    tv1.setTextColor(Color.parseColor("#191919"));
                tv1.setText(cursor.getString(columnIndex));
            }
            if (columnIndex == 3) {
                TextView tv1 = (TextView) view;
                tv1.setText(cursor.getString(columnIndex));
            }
            if (columnIndex == 2) {
                final ImageView image = (ImageView) view;
                Bitmap cachedImage = null;
                try {
                    cachedImage = imageThreadLoader.loadImage(cursor.getString(columnIndex), new ImageThreadLoader.ImageLoadedListener() {
                        public void imageLoaded(Bitmap imageBitmap) {
                            image.setImageBitmap((Bitmap) new SoftReference(imageBitmap).get());
                        }
                    });
                } catch (MalformedURLException mue) {
                    Log.e("Feeds fragment", "Can't load image");
                }
                if (cachedImage != null) {
                    image.setImageBitmap(cachedImage);
                } else image.setImageDrawable(getResources().getDrawable(R.drawable.icon));
            }

图像在单独的线程中加载。

【问题讨论】:

  • 可能是您的列表视图没有回收视图
  • 我的意思是 listview 默认回收视图以有效地使用内存,如果您可以发布您的 getview 方法,这将使事情更清晰

标签: android memory-leaks bitmap android-listview android-viewbinder


【解决方案1】:

我建议您观看有关 ListViews 的 Google IO presentation。它包含节省内存的技术,它帮助我理解了 ListViews 的逻辑。

【讨论】:

    【解决方案2】:

    像这样构建列表视图,制作您的自定义适配器并将其设置为列表视图

    public class InteractiveArrayAdapter extends ArrayAdapter<Model> {
    
        private final List<Model> list;
        private final Activity context;
    
        public InteractiveArrayAdapter(Activity context, List<Model> list) {
            super(context, R.layout.main, list);
            this.context = context;
            this.list = list;
        }
    
        static class ViewHolder {
            protected TextView text;
            protected CheckBox checkbox;
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View view = null;
            if (convertView == null) {
                LayoutInflater inflator = context.getLayoutInflater();
                view = inflator.inflate(R.layout.main, null);
                final ViewHolder viewHolder = new ViewHolder();
                viewHolder.text = (TextView) view.findViewById(R.id.listitem_text);
                viewHolder.checkbox = (CheckBox) view.findViewById(R.id.checkBox1);
                viewHolder.checkbox
                        .setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    
                            public void onCheckedChanged(CompoundButton buttonView,
                                    boolean isChecked) {
                                Model element = (Model) viewHolder.checkbox
                                        .getTag();
                                element.setSelected(buttonView.isChecked());
    
                            }
                        });
                view.setTag(viewHolder);
                viewHolder.checkbox.setTag(list.get(position));
            } else {
                view = convertView;
                ((ViewHolder) view.getTag()).checkbox.setTag(list.get(position));
            }
            ViewHolder holder = (ViewHolder) view.getTag();
            holder.text.setText(list.get(position).getName());
            holder.checkbox.setChecked(list.get(position).isSelected());
            return view;
        }
    }
    

    试试这个方法,你不必要的视图会被回收,执行会更快,希望你能摆脱错误

    【讨论】:

    • 如果我使用你的,我必须将位图列表放入适配器的构造函数中,并且它将在片段的所有生命周期中存储在内存中,但我想从当我看到必要的列表项时外部存储,当它消失时卸载位图(当我滚动列表时)
    • 对不起,我还没有做过类似的事情......但我会试一试......如果我找到任何方法,请告诉你......
    猜你喜欢
    • 2014-05-11
    • 2011-02-27
    • 2013-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多