Android位图缓存



我想从url加载图像到图库视图?

我首先用这个把它们做成位图。

URL aURL = new URL(myRemoteImages[position]);
URLConnection conn = aURL.openConnection();
conn.setUseCaches(true);
conn.connect();
Object response = conn.getContent();
if (response instanceof Bitmap) {
    Bitmap bm = (Bitmap)response;
    InputStream is = conn.getInputStream();  
    /* Buffered is always good for a performance plus. */
    BufferedInputStream bis = new BufferedInputStream(is);
    /* Decode url-data to a bitmap. */
    bm = BitmapFactory.decodeStream(bis);
    bis.close();
    is.close();
    Log.v(imageUrl, "Retrieving image");
    /* Apply the Bitmap to the ImageView that will be returned. */
    i.setImageBitmap(bm);

我如何缓存这个位图?所以当用户滑动屏幕时,它不会一次又一次地重新加载?

编辑:我调用getImage()来获取每个url的文本url。

我在asyncTask中使用这两种方法。调用getImage()和doInBackground我设置图库为imageAdapter.

    private class MyTask extends AsyncTask<Void, Void, Void>{

                @Override
                protected Void doInBackground(Void... arg0) {try {
                            getImages();
                            Log.v("MyTask", "Image 1 retreived");
                            getImage2();
                            Log.v("MyTask", "Image 2 retreived");
                            getImage3();
                            Log.v("MyTask", "Image 3 retreived");
                            getImage4();
                            Log.v("MyTask", "Image 4 retreived");
                        } catch (IOException e) {
                            Log.e("MainMenu retreive image", "Image Retreival failed");
                            e.printStackTrace();
                        }
                    return null;
                }
                @Override
                protected void onPostExecute(Void notUsed){
                    ((Gallery) findViewById(R.id.gallery))
                          .setAdapter(new ImageAdapter(MainMenu.this));

                }
                        }

编辑:getView()方法

    public View getView(int position, View convertView, ViewGroup parent) {
                ImageView i = new ImageView(this.myContext);
                try {
                                URL aURL = new URL(myRemoteImages[position]);
                                URLConnection conn = aURL.openConnection();
                                conn.setUseCaches(true);
                                conn.connect();
                                Object response = conn.getContent();
                                if (response instanceof Bitmap) {
                                  Bitmap bm = (Bitmap)response;

你可以将你的图像存储在SDCard上,在启动你的应用程序时,你需要初始化一个保持HashMap<String,Bitmap>的组件,并初始化带有SDCard中文件夹内容的地图。

当你需要一个图像时,你首先要检查你的HashMap是否包含该图像的键,假设是myMap.contains(myFileName),如果它包含,你将从地图中获取图像,如果图像不包含在你的地图中,你将需要下载它,将id存储在sd卡上并放入你的地图。

我不确定这是否是最好的解决方案,因为如果你有大量的位图,你的应用程序可能会耗尽资源。此外,我认为存储Drawable而不是Bitmap将减少内存消耗。

编辑:对于你的问题,你需要创建一个自定义类,它有一个成员Drawable,并在你第一次创建对象时执行URLConnection。之后,在getView()方法中,您只需使用myObj.getMyDrawable()来访问该特定对象的可绘制对象。

自Android 4以来,可以通过HttpUrlConnection直接缓存HTTP响应。查看本文:http://practicaldroid.blogspot.de/2013/01/utilizing-http-response-cache.html

在android上缓存图像是一个面向关卡的任务:通常在两个级别的缓存中:

  1. Runtime key-value形式的堆内存,其中key是图像的标识符,value是位图对象。(参见这里)
最优化的实现方式是LRUCache:

它基本上为最近访问的项目维护一个LinkedList,其中由于内存限制而转储最早访问的项目。

由于位图的这个后备像素数据存储在本机内存中。它与位图本身是分开的,位图本身存储在Dalvik堆中。本机内存中的像素数据没有以可预测的方式释放,这可能会导致应用程序短暂地超出其内存限制并崩溃。

private LruCache<String, Bitmap> mMemoryCache;
@Override
protected void onCreate(Bundle savedInstanceState) {
// Get max available VM memory, exceeding this amount will throw an
// OutOfMemory exception. Stored in kilobytes as LruCache takes an
// int in its constructor.
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
// Use 1/8th of the available memory for this memory cache.
final int cacheSize = maxMemory / 8;
mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
    @Override
    protected int sizeOf(String key, Bitmap bitmap) {
        // The cache size will be measured in kilobytes rather than
        // number of items.
        return bitmap.getByteCount() / 1024;
    }
};
}

public void addBitmapToMemoryCache(String key, Bitmap bitmap) {
if (getBitmapFromMemCache(key) == null) {
    mMemoryCache.put(key, bitmap);
}
}

public Bitmap getBitmapFromMemCache(String key) {
return mMemoryCache.get(key);
}
  • 磁盘存储:由于内存的存储空间有限,且生命周期有限。
  • 内存缓存有助于加快访问最近查看的图像的速度,但不能依赖于此缓存中可用的图像。

    数据集不确定且庞大的ui组件很容易填满内存,导致图像丢失。

    内存缓存可能会受到影响,例如在后台调用时。

    磁盘缓存可以帮助您使映像保存更长的时间。

    它的一个优化的使用方式是DiskLruCache

    所以当你在内存缓存中查找位图时,结果是nil,你可以尝试从磁盘缓存中访问它,以防你在这里也找不到它,然后从互联网加载它。

    最新更新