我正在尝试下载图像并将所有下载的图像保存在哈希映射中。我尝试使用以下代码:
public class ImageAdapter extends BaseAdapter{
private final Context mContext;
final String[] mImages;
private LayoutInflater mInflater;
private static final String TAG = ImageActivity.class.getSimpleName();
public ImageAdapter(Context context, String[] images){
mContext=context;
mImages=images;
mInflater=(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return mImages.length;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return mImages[position];
}
@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
private static class ViewHolder {
ImageView imageView;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if(convertView==null){
viewHolder=new ViewHolder();
convertView=mInflater.inflate(R.layout.image_layout, parent, false);
viewHolder.imageView=(ImageView) convertView.findViewById(R.id.image_View);
convertView.setTag(viewHolder);
}
else{
viewHolder=(ViewHolder) convertView.getTag();
}
String imageUrl=mImages[position];
ImageDownloader downloader=new ImageDownloader();
Bitmap value=downloader.urlMap.get(imageUrl);
Log.d(TAG, "Print Url:" + value);
if(value==null){
downloader.download(imageUrl,viewHolder.imageView);
}
else
viewHolder.imageView.setImageBitmap(value);
return convertView;
}
}
但是当我调试并检查值包含空值时。它应该包含位图值。
public class ImageDownloader {
private static final int IO_BUFFER_SIZE = 8 * 1024;
private static final String TAG = ImageActivity.class.getSimpleName();
final HashMap<String, Bitmap> urlMap=new HashMap<String, Bitmap>();
public void download(String url, ImageView imageView) {
downloadBitmap(url, imageView);
}
private void downloadBitmap(final String url,final ImageView imageView) {
new AsyncTask<Void, Void, Bitmap>() {
@Override
protected Bitmap doInBackground(Void... params) {
return downloadUrlToStream(url, imageView);
}
protected void onPostExecute(Bitmap bitmap) {
imageView.setImageBitmap(bitmap);
urlMap.put(url, bitmap);
Log.d(TAG, "Print value:" + urlMap);
};
}.execute();
}
为什么它不从哈希映射中检索值?
答案 0 :(得分:3)
您为每次下载创建一个新的下载程序:
ImageDownloader downloader=new ImageDownloader();
downloader.download(imageUrl,viewHolder.imageView);
你的urlMap(存储下载的Bitmap)不是静态的:
final HashMap<String, Bitmap> urlMap=new HashMap<String, Bitmap>();
因此您实际上已经松开了下载的位图,因为您不会存储对ImageDownloader的任何引用。
但是,你不应该让它静止。很快就会耗尽内存,因为这样就可以将所有位图存储在内存中。
推荐的解决方案是使用LRUCache。它非常易于使用,唯一重要的是覆盖sizeOf
正确。以下是您的文档:
http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
答案 1 :(得分:1)
public class ImageAdapter extends BaseAdapter{
private final Context mContext;
final String[] mImages;
private LayoutInflater mInflater;
private static final String TAG = ImageActivity.class.getSimpleName();
ImageDownloader downloader;
public ImageAdapter(Context context, String[] images){
mContext=context;
mImages=images;
mInflater=(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
downloader=new ImageDownloader();
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return mImages.length;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return mImages[position];
}
@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return 0;
}
private static class ViewHolder {
ImageView imageView;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if(convertView==null){
viewHolder=new ViewHolder();
convertView=mInflater.inflate(R.layout.image_layout, parent, false);
viewHolder.imageView=(ImageView) convertView.findViewById(R.id.image_View);
convertView.setTag(viewHolder);
}
else{
viewHolder=(ViewHolder) convertView.getTag();
}
String imageUrl=mImages[position];
Bitmap value=downloader.urlMap.get(imageUrl);
Log.d(TAG, "Print Url:" + value);
if(value==null){
downloader.download(imageUrl,viewHolder.imageView);
}
else
viewHolder.imageView.setImageBitmap(value);
return convertView;
}
}
答案 2 :(得分:0)
如果您想尝试LRU缓存,可以使用此代码
public class GalleryAdapter extends BaseAdapter {
AlertDialog alertDialog = null;
List<GalleryDTO> mDatalist;
Activity context;
private LruCache<String, Bitmap> mMemoryCache;
LocationHandler mLocationHandler = null;
public GalleryAdapter(Activity context, List<GalleryDTO> mDatalist) {
this.context = context;
this.mDatalist = mDatalist;
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
final int cacheSize = maxMemory / 8;
mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
return (int) (getSizeInBytes(bitmap) / 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);
}
public long getSizeInBytes(Bitmap bitmap) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
return bitmap.getByteCount();
} else {
return bitmap.getRowBytes() * bitmap.getHeight();
}
}
@Override
public int getCount() {
return mDatalist.size();
}
@Override
public Object getItem(int position) {
return mDatalist.get(position);
}
@Override
public long getItemId(int position) {
return mDatalist.get(position).photoId;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = context.getLayoutInflater().inflate(
R.layout.list_item_gallery, parent, false);
holder = new ViewHolder();
holder.mPhoto = (ImageView) convertView
.findViewById(R.id.img_photo);
holder.mProgress = (ProgressBar) convertView
.findViewById(R.id.pg_list_item);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
GalleryDTO data = (GalleryDTO) getItem(position);
loadBitmap(data.photoName, holder);
return convertView;
}
private static class ViewHolder {
protected ImageView mPhoto;
protected ProgressBar mProgress;
}
public void loadBitmap(String respath, ViewHolder holder) {
final String imageKey = respath;
final Bitmap bitmap = getBitmapFromMemCache(imageKey);
if (bitmap != null) {
holder.mPhoto.setImageBitmap(bitmap);
holder.mProgress.setVisibility(View.GONE);
} else {
if (cancelPotentialWork(respath, holder.mPhoto, holder.mProgress)) {
final BitmapWorkerTask task = new BitmapWorkerTask(
holder.mPhoto, holder.mProgress);
final AsyncDrawable asyncDrawable = new AsyncDrawable(
context.getResources(), holder.mPlaceHolderBitmap, task);
holder.mPhoto.setImageDrawable(asyncDrawable);
task.execute(respath);
}
}
}
class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
private final WeakReference<ProgressBar> progressbarReference;
private String data = "";
public BitmapWorkerTask(ImageView imageView, ProgressBar progressBar) {
imageViewReference = new WeakReference<ImageView>(imageView);
progressbarReference = new WeakReference<ProgressBar>(progressBar);
}
@Override
protected Bitmap doInBackground(String... params) {
data = params[0];
final Bitmap bitmap = downloadUrlToStream(url);
addBitmapToMemoryCache(String.valueOf(params[0]), bitmap);
return bitmap;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap = null;
}
if (imageViewReference != null && bitmap != null) {
final ImageView imageView = imageViewReference.get();
final ProgressBar mProgressBar = progressbarReference.get();
final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(
imageView, mProgressBar);
if (this == bitmapWorkerTask && imageView != null) {
imageView.setImageBitmap(bitmap);
if (mProgressBar != null)
mProgressBar.setVisibility(View.GONE);
}
}
}
}
static class AsyncDrawable extends BitmapDrawable {
private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
public AsyncDrawable(Resources res, Bitmap bitmap,
BitmapWorkerTask bitmapWorkerTask) {
super(res, bitmap);
bitmapWorkerTaskReference = new WeakReference<BitmapWorkerTask>(
bitmapWorkerTask);
}
public BitmapWorkerTask getBitmapWorkerTask() {
return bitmapWorkerTaskReference.get();
}
}
public static boolean cancelPotentialWork(String data, ImageView imageView,
ProgressBar progressBar) {
final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(
imageView, progressBar);
if (bitmapWorkerTask != null) {
final String bitmapData = bitmapWorkerTask.data;
if (bitmapData != data) {
bitmapWorkerTask.cancel(true);
} else {
return false;
}
}
return true;
}
private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView,
ProgressBar progressBar) {
if (imageView != null) {
final Drawable drawable = imageView.getDrawable();
if (drawable instanceof AsyncDrawable) {
final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
return asyncDrawable.getBitmapWorkerTask();
}
}
return null;
}
}