我的 android listview 图片 内存溢出 解决方案
来源:互联网 发布:如何在淘宝网上开店铺 编辑:程序博客网 时间:2024/06/05 16:03
刚开始接触android开发的时候 经常会碰到一个问题 就是 listview 里的图片太多 会导致 listview 的OutOfMemoryException发生,
而网上却没有很详细的解决方案,只有例如 软引用 ,手动recycle 资源,缩小bitmap等等。(不过貌似都治标不治本,所以以前这个问题 一直困扰了我很久。。。)
即使使用了这些解决方案 也很可能碰到 以下的几个问题
1. 图片 比如 bitmap 或者 drawable 虽然可以用recycle 方法手动释放,但是 释放的时机。
2. 即使使用手动释放,但由于 图片被 imageview 或者其他控件引用 导致发生异常 比如 trying to use a recycled bitmap。
我比较傻瓜的解决方案是
testmemoryadapter.java
package com.testmemoryadapter;import java.util.ArrayList;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageView;public class TestAdapter extends BaseAdapter {private ArrayList list;private LayoutInflater mInflater;private Context context;//这个用来保存 imageview 的引用private ArrayList viewList = new ArrayList();//这个用来 保存 bitmapprivate ArrayList bitmapList = new ArrayList();@Overridepublic int getCount() {// TODO Auto-generated method stubreturn list.size();}@Overridepublic Object getItem(int arg0) {// TODO Auto-generated method stubreturn null;}@Overridepublic long getItemId(int arg0) {// TODO Auto-generated method stubreturn 0;}public TestAdapter(Context context, ArrayList list) {super();this.context = context;this.mInflater = LayoutInflater.from(context);this.list = list;}@Overridepublic View getView(int position, View convertView, ViewGroup arg2) {// TODO Auto-generated method stubconvertView = mInflater.inflate(R.layout.test_list_row, null);ImageView iv = (ImageView) convertView.findViewById(R.id.imageView);//用try catch 块包围住try {setImage(iv);} catch (OutOfMemoryError e) {// 这里就是当内存泄露时 需要做的事情e.printStackTrace();Log.d("memory", "out");//释放内存资源recycleMemory();//将刚才 发生异常没有执行的 代码 再重新执行一次setImage(iv);}return convertView;}//这里是关键private void recycleMemory() {//一屏显示多少行 这里就设置为多少。不设也行 主要是用户体验好 不会将用户看到的图片设为默认图片int showCount = 10;//for (int i = 0; i < viewList.size()-showCount; i++) {ImageView iv = (ImageView) viewList.get(i);/*** * 这里是关键! 将 imageview 设置一张默认的图片 , * 用于解决当释放bitmap的时候 还有其他 控件对他保持引用 * 就不会发生trying to use a recycled bitmap异常了 */iv.setImageResource(R.drawable.default_cover);//从list中去除viewList.remove(i);}//viewList = new ArrayList();for (int i = 0; i < bitmapList.size()-10; i++) {Bitmap bitmap = (Bitmap) bitmapList.get(i);//这里就开始释放bitmap 所占的内存了if (!bitmap.isRecycled()) {bitmap.recycle();System.out.println("recycle ");}//从list中去除bitmapList.remove(i);}//bitmapList = new ArrayList();}private void setImage(ImageView iv){/*** * 从sdcard获取 图片 这张图片 只要不超过 android对于图片大小的限制即可 * 我用了 一张比较大的图片 也通过测试 */Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/test/1.jpg");iv.setImageBitmap(bitmap);//将这个控件 添加到 list里viewList.add(iv);//将要 释放的 bitmap也添加到list里bitmapList.add(bitmap);}}
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ImageView android:id="@+id/imageView" android:layout_width="80dip" android:layout_height="80dip" android:src="@drawable/default_cover"/></LinearLayout>
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <ListView android:id="@+id/testListView" android:layout_width="fill_parent" android:layout_height="fill_parent" > </ListView></LinearLayout>
package com.testmemoryadapter;import java.util.ArrayList;import android.app.Activity;import android.os.Bundle;import android.widget.ListView;public class MainActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ArrayList testList = new ArrayList(); for (int i = 0; i < 30; i++) {testList.add(0);} TestAdapter ta = new TestAdapter(this,testList); ListView lv = (ListView) findViewById(R.id.testListView); lv.setAdapter(ta); }}
接下来放心大胆的测试吧吗哈哈 ,这个解决方案 虽然并不是很规范 但是基本能解决 内存溢出的问题。我用了500k左右的图片 测试下没问题 还有我的运行版本是2.2。希望能给被这个问题困扰的朋友们提供些思路。
http://download.csdn.net/detail/w237or45/4124069
这里是源码下载的位置
用源码里的图片在普通情况下显示10张就 溢出了 ,用了以下的方法后 测试200张 都没有问题~
- 我的 android listview 图片 内存溢出 解决方案
- 我的listview 图片 内存溢出 解决方案
- Android 图片过大内存溢出解决方案
- Android加载大量图片内存溢出解决方案
- listview、gridview上滑加载更多图片,内存溢出outofmemery的解决方案
- Android内存溢出解决方案
- Android内存溢出的原因和解决方案
- Android网络图片加载内存溢出(OOM)解决方案
- android 内存溢出 图片
- 内存溢出的解决方案
- 内存溢出的解决方案
- 解决listview加载图片内存溢出的方案
- 解决listview加载图片内存溢出的方案
- android 下的图片内存溢出处理
- Android图片太多内存溢出的问题
- Android图片的内存溢出问题
- 下载大量图片内存溢出的解决方案(使用SoftReference<Drawable>)
- 彻底解决Java处理图片时,BufferedImage内存溢出的解决方案
- Google的产品质量之道
- Linux命令详解
- 数据结构排序算法总结
- FlashBuilder 和 PureMVC(一)
- linux内存模型之buddy(伙伴)系统三从bootmem到buddy的过渡
- 我的 android listview 图片 内存溢出 解决方案
- PowerDesigner使用技巧
- dos2unix和unix2dos命令使用
- WPF 常用控件 总结 之一
- 百度map的简单例子
- linux 安装oracle9i
- Windows7远程桌面无法全屏显示解决办法
- 提高网站页面加载速度的黄金守则
- perl模块安装方法