這是一篇關於Android ListView異步加載圖片的文章,下面是精品為您提供的一些內容,希望對您有所幫助
對於ListView,相信很多人都很熟悉,因為確實太常見了,所以,做的用戶體驗更好,就成了我們的追求。。。
常見的ListView中很少全是文字的,一般都是圖文共存的,而圖片的來源是服務器端(很少有寫在客戶端的吧。。。考慮客戶端的大小和更新的問題),所以,網絡問題就成了圖片是否能順利加載成功的決定性因素了。大家都知道每次啟動一個Android應用,都會啟動一個UI主線程,主要是響應用戶的交互,如果我們把不確定的獲取網絡圖片的操作放在UI主線程,結果也就不確定了。。。當然,如果你網絡足夠好的話,應該問題不大,但是,網絡誰能保證呢?所以就出現了“異步加載”的方法!
我先敘述一下異步加載的原理,說的通俗一點就是UI主線程繼續做與用戶交互的響應監聽和操作,而加載圖片的任務交到其他線程中去做,當圖片加載完成之後,再跟據某種機制(比如回調)繪制到要顯示的控件中。
首先,貼出AsyncBitmapLoader.java,這個類是關鍵,主要做的就是當加載圖片的時候,去緩沖區查找,如果有的話,則立刻返回Bitmap對象,省掉再去網絡服務器下載的時間和流量。
[java]
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.util.HashMap;
import onerain.ald.common.HttpUtils;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message;
import android.widget.ImageView;
/**
* @author oneRain
**/
public class AsyncBitmapLoader
{
/**
* 內存圖片軟引用緩沖
*/
private HashMap> imageCache = null;
public AsyncBitmapLoader()
{
imageCache = new HashMap>();
}
public Bitmap loadBitmap(final ImageView imageView, final String imageURL, final ImageCallBack imageCallBack)
{
//在內存緩存中,則返回Bitmap對象
if(imageCache.containsKey(imageURL))
{
SoftReference reference = imageCache.get(imageURL);
Bitmap bitmap = reference.get();
if(bitmap != null)
{
return bitmap;
}
}
else
{
/**
* 加上一個對本地緩存的查找
*/
String bitmapName = imageURL.substring(imageURL.lastIndexOf("/") + 1);
File cacheDir = new File("/mnt/sdcard/test/");
File[] cacheFiles = cacheDir.listFiles();
int i = 0;
for(; i
{
if(bitmapName.equals(cacheFiles[i].getName()))
{
break;
}
}
if(i < cacheFiles.length)
{
return BitmapFactory.decodeFile("/mnt/sdcard/test/" + bitmapName);
}
}
final Handler handler = new Handler()
{
/* (non-Javadoc)
* @see android.os.Handler#handleMessage(android.os.Message)
*/
@Override
public void handleMessage(Message msg)
{
// TODO Auto-generated method stub
imageCallBack.imageLoad(imageView, (Bitmap)msg.obj);
}
};
//如果不在內存緩存中,也不在本地(被jvm回收掉),則開啟線程下載圖片
new Thread()
{
/* (non-Javadoc)
* @see java.lang.Thread#run()
*/
@Override
public void run()
{
// TODO Auto-generated method stub
InputStream bitmapIs = HttpUtils.getStreamFromURL(imageURL);
Bitmap bitmap = BitmapFactory.decodeStream(bitmapIs);
imageCache.put(imageURL, new SoftReference(bitmap));
Message msg = handler.obtainMessage(0, bitmap);
handler.sendMessage(msg);
File dir = new File("/mnt/sdcard/test/");
if(!dir.exists())
{
dir.mkdirs();
}
File bitmapFile = new File("/mnt/sdcard/test/" +
imageURL.substring(imageURL.lastIndexOf("/") + 1));
if(!bitmapFile.exists())
{
try
{
bitmapFile.createNewFile();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
FileOutputStream fos;
try
{
fos = new FileOutputStream(bitmapFile);
bitmap.compress(Bitmap.CompressFormat.JPEG,
100, fos);
fos.close();
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
return null;
}
/**
* 回調接口
* @author onerain
*
*/
public interface ImageCallBack
{
public void imageLoad(ImageView imageView, Bitmap bitmap);
}
}
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.util.HashMap;
import onerain.ald.common.HttpUtils;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message;
import android.widget.ImageView;
/**
* @author oneRain
**/
public class AsyncBitmapLoader
{
/**
* 內存圖片軟引用緩沖
*/
private HashMap> imageCache = null;
public AsyncBitmapLoader()
{
imageCache = new HashMap>();
}
public Bitmap loadBitmap(final ImageView imageView, final String imageURL, final ImageCallBack imageCallBack)
{
//在內存緩存中,則返回Bitmap對象
if(imageCache.containsKey(imageURL))
{
SoftReference reference = imageCache.get(imageURL);
Bitmap bitmap = reference.get();
if(bitmap != null)
{
return bitmap;
}
}
else
{
/**
* 加上一個對本地緩存的查找
*/
String bitmapName = imageURL.substring(imageURL.lastIndexOf("/") + 1);
File cacheDir = new File("/mnt/sdcard/test/");
File[] cacheFiles = cacheDir.listFiles();
int i = 0;
for(; i
{
if(bitmapName.equals(cacheFiles[i].getName()))
{
break;
}
}
if(i < cacheFiles.length)
{
return BitmapFactory.decodeFile("/mnt/sdcard/test/" + bitmapName);
}
}
final Handler handler = new Handler()
{
/* (non-Javadoc)
* @see android.os.Handler#handleMessage(android.os.Message)
*/
@Override
public void handleMessage(Message msg)
{
// TODO Auto-generated method stub
imageCallBack.imageLoad(imageView, (Bitmap)msg.obj);
}
};
//如果不在內存緩存中,也不在本地(被jvm回收掉),則開啟線程下載圖片
new Thread()
{
/* (non-Javadoc)
* @see java.lang.Thread#run()
*/
@Override
public void run()
{
// TODO Auto-generated method stub
InputStream bitmapIs = HttpUtils.getStreamFromURL(imageURL);
Bitmap bitmap = BitmapFactory.decodeStream(bitmapIs);
imageCache.put(imageURL, new SoftReference(bitmap));
Message msg = handler.obtainMessage(0, bitmap);
handler.sendMessage(msg);
File dir = new File("/mnt/sdcard/test/");
if(!dir.exists())
{
dir.mkdirs();
}
File bitmapFile = new File("/mnt/sdcard/test/" +
imageURL.substring(imageURL.lastIndexOf("/") + 1))