android Okhttp 网络请求imageView 图片,显示在 ListView中且图片不一
时间: 2024-03-11 20:49:13 浏览: 169
要在 ListView 中显示多张不同的图片,可以使用 OkHttp 进行网络请求获取图片,并根据图片的 URL 地址将 Bitmap 缓存到 LruCache 中,以避免重复请求相同的图片。具体实现步骤如下:
1. 在 Adapter 中定义 LruCache 对象,用于缓存 Bitmap:
```java
private LruCache<String, Bitmap> mBitmapCache;
```
2. 在构造方法中初始化 LruCache:
```java
public MyAdapter(Context context, List<String> imageUrlList) {
mContext = context;
mImageUrlList = imageUrlList;
int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
int cacheSize = maxMemory / 8;
mBitmapCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getByteCount() / 1024;
}
};
}
```
其中,`maxMemory` 是获取当前应用程序最大可用内存大小,`cacheSize` 是 LruCache 的缓存大小,这里设置为最大可用内存大小的 1/8。
3. 在 getView() 方法中获取 ViewHolder,如果 convertView 为 null,则新建一个 ViewHolder,并使用 LayoutInflater 加载布局文件。接着从 LruCache 中获取缓存的 Bitmap,如果 LruCache 中没有缓存该 Bitmap,则调用 loadImage() 方法从网络获取 Bitmap 并缓存到 LruCache 中:
```java
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(R.layout.item_layout, parent, false);
holder = new ViewHolder();
holder.imageView = convertView.findViewById(R.id.image_view);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
// 从 LruCache 中获取 Bitmap
String imageUrl = mImageUrlList.get(position);
Bitmap bitmap = mBitmapCache.get(imageUrl);
if (bitmap != null) {
holder.imageView.setImageBitmap(bitmap);
} else {
// 缓存中没有该 Bitmap,则从网络获取
loadImage(holder.imageView, imageUrl);
}
return convertView;
}
```
4. 在 loadImage() 方法中使用 OkHttp 进行网络请求,获取图片并设置到 ImageView 中。同时将 Bitmap 缓存到 LruCache 中:
```java
private void loadImage(final ImageView imageView, final String imageUrl) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(imageUrl)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
InputStream inputStream = response.body().byteStream();
final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
mHandler.post(new Runnable() {
@Override
public void run() {
imageView.setImageBitmap(bitmap);
// 将 Bitmap 缓存到 LruCache 中
mBitmapCache.put(imageUrl, bitmap);
}
});
}
});
}
```
其中,`mHandler` 是 Handler 对象,用于在子线程中更新 UI。首先从 LruCache 中获取缓存的 Bitmap,如果有缓存则直接显示在 ImageView 中;如果没有缓存,则使用 OkHttp 进行网络请求获取 Bitmap,并将 Bitmap 缓存到 LruCache 中。需要注意的是,由于网络请求是异步执行的,因此需要使用 Handler 来更新 UI 和缓存 Bitmap,否则会出现异常。
阅读全文