有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Lru缓存列表视图映像问题

我的列表视图中有我的活动的图像,在添加LRU缓存之前效果很好。当我第一次加载图像时(如果我没有滚动它),第一个元素会在我加载的所有图像之间更改其图像

我的LRU缓存看起来像

public class Image {
    private static LruCache<String, Bitmap>     mMemoryCache    = null;
    private static int                          cacheSize       = 1024 * 1024 * 10;

    private static class AsyncLoader extends AsyncTask<String, Void, Bitmap> {
        private ImageView   mTarget;

        public AsyncLoader(ImageView target) {
            this.mTarget = target;
        }

        @Override
        protected void onPreExecute() {
            mTarget.setTag(this);
        }

        @Override
        protected Bitmap doInBackground(String...urls) {
            String url = urls[0];

            Bitmap result = null;

            if (url != null) {
                result = load(url);

                if (result != null) {
                    mMemoryCache.put(url, result);
                }
            }

            return result;
        }

        @Override
        protected void onPostExecute(Bitmap result) {
            if (mTarget.getTag() == this) {
                mTarget.setTag(null);
                if (result != null) mTarget.setImageBitmap(result);
            }
        }
    }

    public static Bitmap load(String urlString) {
        if (urlString == null || urlString.length() == 0) return null;

        Bitmap bitmap = null;
        URL url = null;

        try {
            url = new URL(urlString);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }

        try {
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setDoInput(true);
            conn.connect();
            InputStream is = conn.getInputStream();
            bitmap = BitmapFactory.decodeStream(is);
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return bitmap;
    }

    public static void loadToView(String url, ImageView view) {
        if (url == null || url.length() == 0) return;
        if (mMemoryCache == null) {
            mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
                @Override
                protected int sizeOf(String key, Bitmap bitmap) {
                    return (bitmap.getRowBytes() * bitmap.getHeight());
                }
            };
        }

        Bitmap bitmap = getBitmapFromMemCache(url);
        if (bitmap == null) {
            final AsyncLoader task = (AsyncLoader) new AsyncLoader(view);
            view.setTag(task);
            task.execute(url);
        } else {
            view.setImageBitmap(bitmap);
        }
    }
}

用法:

Image.loadToView("http://image_url", (ImageView) view.findViewById(R.id.img_thumbnail));

这就是我的BaseAdapter getView的外观

@Override
public View getView(final int position, View view, ViewGroup parent) {
    if (view == null) view = inflater.inflate(R.layout.list_item, null);

    ((TextView) view.findViewById(R.id.txt_name)).setText(filtered_data.get(position).name);

    Image.loadToView("http://graph.facebook.com/" + filtered_data.get(position).id + "/picture", (ImageView) view.findViewById(R.id.img_thumbnail));

    return view;
}

共 (1) 个答案

  1. # 1 楼答案

    我发现在listview问题上阅读了很多关于图像的内容,它与listview回收有关,还有一些相关的帖子:

    我在onPostExecute方法中添加了else语句,如果标记不是在标记上设置的,我会取消它

    固定代码

    public class Image {
        private static LruCache<String, Bitmap>     mMemoryCache    = null;
        private static int                          cacheSize       = 1024 * 1024 * 10;
    
        private static class AsyncLoader extends AsyncTask<String, Void, Bitmap> {
            private ImageView   mTarget;
    
            public AsyncLoader(ImageView target) {
                this.mTarget = target;
            }
    
            @Override
            protected void onPreExecute() {
                mTarget.setTag(this);
            }
    
            @Override
            protected Bitmap doInBackground(String...urls) {
                String url = urls[0];
    
                Bitmap result = null;
    
                if (url != null) {
                    result = load(url);
    
                    if (result != null) {
                        mMemoryCache.put(url, result);
                    }
                }
    
                return result;
            }
    
            @Override
            protected void onPostExecute(Bitmap result) {
                if (mTarget.getTag() == this) {
                    mTarget.setTag(null);
                    if (result != null) mTarget.setImageBitmap(result);
                } else if (mTarget.getTag() != null) {
                    ((AsyncLoader) mTarget.getTag()).cancel(true);
                    mTarget.setTag(null);
                }
            }
        }
    
        public static Bitmap load(String urlString) {
            if (urlString == null || urlString.length() == 0) return null;
    
            Bitmap bitmap = null;
            URL url = null;
    
            try {
                url = new URL(urlString);
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
    
            try {
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setDoInput(true);
                conn.connect();
                InputStream is = conn.getInputStream();
                bitmap = BitmapFactory.decodeStream(is);
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            return bitmap;
        }
    
        public static void loadToView(String url, ImageView view) {
            if (url == null || url.length() == 0) return;
            if (mMemoryCache == null) {
                mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
                    @Override
                    protected int sizeOf(String key, Bitmap bitmap) {
                        return (bitmap.getRowBytes() * bitmap.getHeight());
                    }
                };
            }
    
            Bitmap bitmap = getBitmapFromMemCache(url);
            if (bitmap == null) {
                final AsyncLoader task = (AsyncLoader) new AsyncLoader(view);
                view.setTag(task);
                task.execute(url);
            } else {
                view.setImageBitmap(bitmap);
            }
        }
    }
    

    我认为谷歌需要解决这个问题,或者提供一个更干净的解决方案,因为(在我看来)谷歌在构建一些东西上失败了,开发者只需要关注构建自己的应用程序,而不需要浪费时间寻找解决sdk问题的方法