我想从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上缓存图像是一个面向关卡的任务:通常在两个级别的缓存中:
最优化的实现方式是LRUCache:
- Runtime key-value形式的堆内存,其中key是图像的标识符,value是位图对象。(参见这里)
它基本上为最近访问的项目维护一个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,你可以尝试从磁盘缓存中访问它,以防你在这里也找不到它,然后从互联网加载它。