使用通用图像加载程序的内存不足错误和图像刷新

时间:2012-12-13 07:58:46

标签: android android-listview universal-image-loader

我正在使用通用图像加载器在ListView中将图像显示为缩略图但是我得到了内存不足错误,当我滚动列表时,新列表中的列表未打开时具有第一个视图的图像滚动阶段但是图像被设置为应该是正确的图像。

public class NewAdapter extends BaseAdapter {

    private Activity activity;
    private ArrayList<String> movieThumbnail;
    private ArrayList<String> movieText;
    private static LayoutInflater inflater=null;
    static File cacheDir;

    ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(activity)
    .memoryCache(new WeakMemoryCache())
    .denyCacheImageMultipleSizesInMemory()
    .discCache(new UnlimitedDiscCache(cacheDir))
    .threadPoolSize(5)
    .imageDownloader(new URLConnectionImageDownloader(120 * 1000, 120 * 1000))
    .enableLogging()
    .build();

    DisplayImageOptions options = new DisplayImageOptions.Builder()
    .cacheOnDisc()
    .cacheInMemory()
    .bitmapConfig(Bitmap.Config.RGB_565)
    .imageScaleType(ImageScaleType.IN_SAMPLE_INT)
    .build();

    private ImageLoader imageLoader= ImageLoader.getInstance();

    public NewAdapter(Activity a, ArrayList<String> movieThumbnail, ArrayList<String> movieText) {
        activity = a;
        /*data=d;*/
        this.movieThumbnail = movieThumbnail;
        this.movieText = movieText;
        inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
            cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"JunkFolder");
        else
            cacheDir=activity.getCacheDir();
        if(!cacheDir.exists())
            cacheDir.mkdirs();

        imageLoader.init(config);

    }

    public int getCount() {
        return movieText.size();
    }

    public Object getItem(int position) {
        return position;
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        View vi=convertView;
        if(convertView==null)
              vi = inflater.inflate(R.layout.listrow, null);

        TextView text=(TextView)vi.findViewById(R.id.rowListTextView);
        ImageView image=(ImageView)vi.findViewById(R.id.movieImage);
        text.setText(movieText.get(position));
        imageLoader.displayImage(movieThumbnail.get(position), image, options);
        return vi;
    }
}

这里是ImageView和TextView的Xml布局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/text_relativelayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/latest_list_toggle" />


    <ImageView
        android:id="@+id/movieImage"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_marginLeft="12dp"
        android:layout_marginTop="14dp" />

    <TextView
        android:id="@+id/rowListTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/movieImage"
        android:paddingBottom="10dp"
        android:paddingLeft="10dp"
        android:paddingRight="21dp"
        android:paddingTop="20dp"
        android:text="@string/app_name"
        android:textColor="@android:color/black"
        android:textSize="17sp"
        android:textStyle="bold" />
</RelativeLayout>

3 个答案:

答案 0 :(得分:11)

在DisplayImageOptions中设置.resetViewBeforeLoading()

答案 1 :(得分:4)

接下来尝试(所有这些或几个):

减少配置中的线程池大小(.threadPoolSize(...))。建议使用1 - 5。 使用

 .bitmapConfig(Bitmap.Config.RGB_565)     
显示选项中的

。 RGB_565中的位图消耗的内存比ARGB_8888少2倍。 使用

.memoryCache(new WeakMemoryCache()) 

配置或禁用内存中的缓存 在显示选项中(不要调用.cacheInMemory())。 使用

.imageScaleType(ImageScaleType.IN_SAMPLE_INT)
显示选项中的

。或者尝试

.imageScaleType(ImageScaleType.EXACTLY).

避免使用RoundedBitmapDisplayer。它使用ARGB_8888配置创建新的Bitmap对象,以便在工作期间显示。

答案 2 :(得分:1)

确保在ImageLoader中将图像大小设为需要

// decodes image and scales it to reduce memory consumption
    private Bitmap decodeFile(File f) {
        try {
            // decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(new FileInputStream(f), null, o);

            // Find the correct scale value. It should be the power of 2.
            final int REQUIRED_SIZE = 70;
            int width_tmp = o.outWidth, height_tmp = o.outHeight;
            int scale = 1;
            while (true) {
                if (width_tmp / 2 < REQUIRED_SIZE
                        || height_tmp / 2 < REQUIRED_SIZE)
                    break;
                width_tmp /= 2;
                height_tmp /= 2;
                scale *= 2;
            }

            // decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize = scale;
            return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
        } catch (FileNotFoundException e) {
        }
        return null;
    }