使用Universal Image Loader时出现内存不足错误并且图片得到刷新

4
我正在使用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>

我解决了在listView刷新时设置正确图像的问题。之前我在调用Imageloader.displayImage()时没有传递DisplayImageOption变量。现在它正常工作了。 :) - Nitin Bathija
3个回答

11
在DisplayImageOptions中设置".resetViewBeforeLoading()"。

我正在使用Base Adapter加载一张图片,在Inflater ImageView中使用Picasso设置图片,并尝试使用Image Loader,但是在使用Universal Image Loader时,在占位符中加载图片时会出现内存不足异常,特别是在三星S4设备上使用Picasso也会出现此问题。我还尝试使用最新的Picasso jar文件,但没有解决方案。https://github.com/square/picasso/issues/623我已经尝试了large hip = true和bitmap.recycle,但无法解决它。 - Ajay Pandya

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配置的位图对象进行显示。


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;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接