ListView asynchronous loading image implementation idea
- 2020-05-09 19:19:55
- OfStack
In application development, ListView is often used to load data. It is quite common to load pictures and text. The text is ok, but the loading speed of pictures is slow when it is requested from the network. The following is a list of one of the asynchronously loaded picture solutions I used in my project. The code is incomplete and gives the core.
The general idea is this:
1. Use soft reference to cache image Bitmap, and use image URL as Key for cache lookup;
2. Set two levels of cache, level 1 is SoftReference, level 2 is local SD card;
3. If the image is not retrieved from the two caches, it will be obtained from the server and added to the cache;
4. Update UI via callback interface after loading;
The following is the key code of asynchronous loading, in which 1 of the tool classes are not given, but can be implemented by myself. For example, HttpRequest is a class I wrote by myself.
In the ListView adapter getView method:
Where asyncImageLoader is initialized in the adapter constructor to form a cache. This allows you to load ListView's images asynchronously, which is a much better user experience than direct loading, which can create a sticky interface. Here is the loading of 1 image, if the ListView item image is not fixed, it may be 1, 2, 3, which way to use, you can think 1, and can start to discuss 1, including the implementation of ListView scrolling without loading data is a necessary step to optimize the loading of ListView.
The general idea is this:
1. Use soft reference to cache image Bitmap, and use image URL as Key for cache lookup;
2. Set two levels of cache, level 1 is SoftReference, level 2 is local SD card;
3. If the image is not retrieved from the two caches, it will be obtained from the server and added to the cache;
4. Update UI via callback interface after loading;
The following is the key code of asynchronous loading, in which 1 of the tool classes are not given, but can be implemented by myself. For example, HttpRequest is a class I wrote by myself.
public class AsyncImageLoader {
//Cache for image(Type String is the URL of image,the second parameter is soft reference)
private HashMap<String, SoftReference<Bitmap>> imageCache = null;
private Activity context;
public AsyncImageLoader(Activity context){
this.context = context;
imageCache = new HashMap<String, SoftReference<Bitmap>>();
}
public Bitmap loadImage(final ImageView imageView,final String imageURL,final ImageCallBack imageCallBack){
//If the cache contains the reference of bitmap then return
if (imageCache.containsKey(imageURL)) {
SoftReference<Bitmap> bitmapReference = imageCache.get(imageURL);
Bitmap bitmap = bitmapReference.get();
if (bitmap != null) {
return bitmap;
}
}
//Second cache,search local SD card
else {
String fileName = StringUtil.namePicture(imageURL);// Get file name
boolean isExist = SystemUtils.findPhotoFromSDCard(Constant.INFO_PATH, fileName);
if (isExist) {// Whether in SD Card picture
Bitmap bitmap = SystemUtils.getPhotoFromSDCard(Constant.INFO_PATH, fileName);
return bitmap;
}
}
final Handler myHandler = new Handler(){
@Override
public void handleMessage(Message msg)
{
imageCallBack.setImage(imageView, (Bitmap)msg.obj);
}
};
//If the bitmap not exists in cache or SD card,then get it from net
new Thread(){
@Override
public void run() {
// TODO Auto-generated method stub
boolean isNetwork = SystemUtils.checkNetwork(context);
if (isNetwork) {
InputStream photoStream = HttpRequest.getImageStream(imageURL);// I wrote it myself 1 Class, the purpose is to pass URL The address gets the image input stream from the server
Bitmap bitmap;
try {
bitmap = ImageTools.getResizeBitmap(photoStream, 128, 128);
if (bitmap != null) {
String fileName = StringUtil.namePicture(imageURL);
//Save image to SD card
SystemUtils.savePhotoToSDCard(bitmap, fileName, Constant.INFO_PATH);
//Put soft reference to cache
imageCache.put(imageURL, new SoftReference<Bitmap>(bitmap));
//Send message to update UI
Message message = myHandler.obtainMessage(0, bitmap);
myHandler.sendMessage(message);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();
return null;
}
/**
* Interface for load image
* @author Ryan
*
*/
public interface ImageCallBack{
//Set image for imageview through bitmap
public void setImage(ImageView imageView,Bitmap bitmap);
}
}
In the ListView adapter getView method:
Bitmap bitmap1 = asyncImageLoader.loadImage(viewHolder.imageView1, url1, new ImageCallBack() {
@Override
public void setImage(ImageView imageView, Bitmap bitmap) {
// TODO Auto-generated method stub
imageView.setImageBitmap(bitmap);
}
});
if (bitmap1 != null) {
viewHolder.imageView1.setImageBitmap(bitmap1);
}else {
viewHolder.imageView1.setImageResource(R.drawable.image_bg);
}
Where asyncImageLoader is initialized in the adapter constructor to form a cache. This allows you to load ListView's images asynchronously, which is a much better user experience than direct loading, which can create a sticky interface. Here is the loading of 1 image, if the ListView item image is not fixed, it may be 1, 2, 3, which way to use, you can think 1, and can start to discuss 1, including the implementation of ListView scrolling without loading data is a necessary step to optimize the loading of ListView.