ListView异步图像加载器是Android开发中用于高效加载和显示列表项中网络或本地图片的解决方案。由于ListView的复用机制和UI线程限制,直接在主线程加载图片会导致卡顿、内存溢出等问题,异步加载器通过后台线程加载、内存缓存和磁盘缓存等机制解决这些问题。
原因:ListView复用View时,异步加载完成前View已被复用
解决方案:
// 在getView()中设置tag
imageView.setTag(imageUrl);
imageLoader.loadImage(imageUrl, new ImageLoader.ImageListener() {
@Override
public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) {
if (imageView.getTag().equals(imageUrl)) {
imageView.setImageBitmap(response.getBitmap());
}
}
});
原因:加载大图或缓存过多图片
解决方案:
原因:频繁创建线程或同步加载
解决方案:
public class ImageLoader {
private LruCache<String, Bitmap> memoryCache;
private ExecutorService executorService;
private Handler handler = new Handler(Looper.getMainLooper());
public ImageLoader() {
// 初始化内存缓存
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
final int cacheSize = maxMemory / 8;
memoryCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
return bitmap.getByteCount() / 1024;
}
};
executorService = Executors.newFixedThreadPool(5);
}
public void loadImage(final String url, final ImageView imageView) {
final String imageKey = String.valueOf(url.hashCode());
// 检查内存缓存
final Bitmap bitmap = getBitmapFromMemCache(imageKey);
if (bitmap != null) {
imageView.setImageBitmap(bitmap);
return;
}
// 设置占位图
imageView.setImageResource(R.drawable.placeholder);
// 检查View是否已被复用
imageView.setTag(url);
executorService.submit(new Runnable() {
@Override
public void run() {
Bitmap bitmap = downloadBitmap(url);
if (bitmap != null) {
addBitmapToMemoryCache(imageKey, bitmap);
handler.post(new Runnable() {
@Override
public void run() {
if (imageView.getTag().equals(url)) {
imageView.setImageBitmap(bitmap);
}
}
});
}
}
});
}
private Bitmap downloadBitmap(String url) {
HttpURLConnection connection = null;
try {
URL imageUrl = new URL(url);
connection = (HttpURLConnection) imageUrl.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
return BitmapFactory.decodeStream(input);
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
private void addBitmapToMemoryCache(String key, Bitmap bitmap) {
if (getBitmapFromMemCache(key) == null) {
memoryCache.put(key, bitmap);
}
}
private Bitmap getBitmapFromMemCache(String key) {
return memoryCache.get(key);
}
}
通过合理实现异步图像加载器,可以显著提升列表的流畅性和用户体验。
没有搜到相关的文章