问题
I have this list of people and each person has an avatar. There's a default avatar for everyone and later you can change it (the app saves the resized and circle-cropped image to the sd).
Here's my approach:
<ImageView
android:id="@+id/photo_list_item"
android:layout_width="70dip"
android:layout_height="70dip"
android:layout_marginRight="16dip"
android:contentDescription="@string/avatar_descp"
android:src="@drawable/defavatar" >
</ImageView>
This is part of the item that forms the list. defavatar
is the default avatar I already talked about. Then:
String m = person.getAvatar();
if(!m.equals(""))
{
loadBitmap("file://"+m, avatar);
}
getAvatar()
gets the path of the avatar of the db. If not null:
public void loadBitmap(String resId, ImageView imageView)
{
BitmapWorkerTask task = new BitmapWorkerTask(imageView);
task.execute(resId);
}
class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap>
{
private final WeakReference<ImageView> imageViewReference;
public BitmapWorkerTask(ImageView imageView)
{
// Use a WeakReference to ensure the ImageView can be garbage collected
imageViewReference = new WeakReference<ImageView>(imageView);
}
// Decode image in background.
@Override
protected Bitmap doInBackground(String... params)
{
return decodeSampledBitmapFromResource(getContext(), Uri.parse(params[0]), 320, 320);
}
// Once complete, see if ImageView is still around and set bitmap.
@Override
protected void onPostExecute(Bitmap bitmap)
{
if (imageViewReference != null && bitmap != null)
{
final ImageView imageView = imageViewReference.get();
if (imageView != null)
{
imageView.setImageBitmap(bitmap);
}
}
}
}
This code is copied mostly from the official Android Dev Guides.
My problem is this: Everytime the image is loaded, again and again (and also I see first the default avatar and some ms later the new avatar instead, and this is not very nice).
I'm guessing that I can use the WeakReference (which is a cache of the image, right?) that holds in the memory until a memory leak. Am I right? What can I do?
回答1:
Do not use WeakReference
. Use an LruCache instead. Android's garbage collector is very aggressive and weak references to memory-intensive images would be cleared by the garbage collector very quickly. From Google:
In the past, a popular memory cache implementation was a SoftReference or WeakReference bitmap cache, however this is not recommended. Starting from Android 2.3 (API Level 9) the garbage collector is more aggressive with collecting soft/weak references which makes them fairly ineffective.
For help on using LruCache
, see this link: Caching Bitmaps.
Also, as @Sainath suggested, use a third-party image loading library instead. There is a lot to consider when handling image loading in Android, so it's best to use a library that already takes all those factors into consideration.
回答2:
Ya this is good to see from android developer site, but you should use a third party library; image loading is very costly operation which will depend on many factors
I had used Picasso library in many applications, which is very good at performance as well as memory consumption.
You can find it from http://square.github.io/picasso/
来源:https://stackoverflow.com/questions/23522560/not-loading-an-image-from-sd-everytime-use-weakreference