我正在使用 Android,我正在使用 Imagedownloader 类下载图像并按顺序设置为列表视图项目中的图像视图。
但是当我连续滚动列表视图时,有时会出现 Outoffmemory 异常。
例外情况如下。
01-28 15:30:47.580: E/AndroidRuntime(3723): FATAL EXCEPTION: main
01-28 15:30:47.580: E/AndroidRuntime(3723): java.lang.OutOfMemoryError
01-28 15:30:47.580: E/AndroidRuntime(3723): at android.graphics.Bitmap.nativeCreate(Native Method)
01-28 15:30:47.580: E/AndroidRuntime(3723): at android.graphics.Bitmap.createBitmap(Bitmap.java:605)
01-28 15:30:47.580: E/AndroidRuntime(3723): at android.graphics.Bitmap.createBitmap(Bitmap.java:551)
01-28 15:30:47.580: E/AndroidRuntime(3723): at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:437)
01-28 15:30:47.580: E/AndroidRuntime(3723): at android.graphics.BitmapFactory.finishDecode(BitmapFactory.java:618)
01-28 15:30:47.580: E/AndroidRuntime(3723): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:593)
01-28 15:30:47.580: E/AndroidRuntime(3723): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:445)
01-28 15:30:47.580: E/AndroidRuntime(3723): at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:773)
01-28 15:30:47.580: E/AndroidRuntime(3723): at android.content.res.Resources.loadDrawable(Resources.java:1968)
01-28 15:30:47.580: E/AndroidRuntime(3723): at android.content.res.Resources.getDrawable(Resources.java:677)
01-28 15:30:47.580: E/AndroidRuntime(3723): at com.lt.appmedia.customise.SpeakersAdapter.getView(SpeakersAdapter.java:118)
01-28 15:30:47.580: E/AndroidRuntime(3723): at android.widget.AbsListView.obtainView(AbsListView.java:2197)
01-28 15:30:47.580: E/AndroidRuntime(3723): at android.widget.ListView.makeAndAddView(ListView.java:1774)
01-28 15:30:47.580: E/AndroidRuntime(3723): at android.widget.ListView.fillDown(ListView.java:672)
01-28 15:30:47.580: E/AndroidRuntime(3723): at android.widget.ListView.fillGap(ListView.java:636)
01-28 15:30:47.580: E/AndroidRuntime(3723): at android.widget.AbsListView.trackMotionScroll(AbsListView.java:5259)
01-28 15:30:47.580: E/AndroidRuntime(3723): at android.widget.AbsListView$FlingRunnable.run(AbsListView.java:4467)
01-28 15:30:47.580: E/AndroidRuntime(3723): at android.os.Handler.handleCallback(Handler.java:605)
01-28 15:30:47.580: E/AndroidRuntime(3723): at android.os.Handler.dispatchMessage(Handler.java:92)
01-28 15:30:47.580: E/AndroidRuntime(3723): at android.os.Looper.loop(Looper.java:137)
01-28 15:30:47.580: E/AndroidRuntime(3723): at android.app.ActivityThread.main(ActivityThread.java:4511)
01-28 15:30:47.580: E/AndroidRuntime(3723): at java.lang.reflect.Method.invokeNative(Native Method)
01-28 15:30:47.580: E/AndroidRuntime(3723): at java.lang.reflect.Method.invoke(Method.java:511)
01-28 15:30:47.580: E/AndroidRuntime(3723): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:980)
01-28 15:30:47.580: E/AndroidRuntime(3723): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:747)
01-28 15:30:47.580: E/AndroidRuntime(3723): at dalvik.system.NativeStart.main(Native Method)
我不知道如何解决这个问题。
ImageDownloader 类是
public class ImageDownloader {
private final Map<String, SoftReference<Drawable>> mCache = new HashMap<String, SoftReference<Drawable>>();
private final LinkedList<Drawable> mChacheController = new LinkedList<Drawable>();
private ExecutorService mThreadPool;
private final Map<ImageView, String> mImageViews = Collections
.synchronizedMap(new WeakHashMap<ImageView, String>());
public static int MAX_CACHE_SIZE = 150;
public int THREAD_POOL_SIZE = 3;
private static ImageDownloader imageDownloader;
public static ImageDownloader shareInstance(){
if(imageDownloader == null){
imageDownloader = new ImageDownloader();
}
return imageDownloader;
}
/**
* Constructor
*/
public ImageDownloader() {
mThreadPool = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
}
/**
* Clears all instance data and stops running threads
*/
public void Reset() {
ExecutorService oldThreadPool = mThreadPool;
mThreadPool = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
oldThreadPool.shutdownNow();
mChacheController.clear();
mCache.clear();
mImageViews.clear();
}
public void loadDrawable(final String url, final ImageView imageView,
Drawable placeholder) {
mImageViews.put(imageView, url);
Drawable drawable = getDrawableFromCache(url);
// check in UI thread, so no concurrency issues
if (drawable != null) {
// Log.d(null, "Item loaded from mCache: " + url);
imageView.setBackgroundDrawable(drawable);
} else {
imageView.setBackgroundDrawable(placeholder);
queueJob(url, imageView, placeholder);
}
}
private Drawable getDrawableFromCache(String url) {
if (mCache.containsKey(url)) {
return mCache.get(url).get();
}
return null;
}
private synchronized void putDrawableInCache(String url, Drawable drawable) {
int chacheControllerSize = mChacheController.size();
if (chacheControllerSize > MAX_CACHE_SIZE)
mChacheController.subList(0, MAX_CACHE_SIZE / 2).clear();
mChacheController.addLast(drawable);
mCache.put(url, new SoftReference<Drawable>(drawable));
}
private void queueJob(final String url, final ImageView imageView,
final Drawable placeholder) {
/* Create handler in UI thread. */
final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
String tag = mImageViews.get(imageView);
if (tag != null && tag.equals(url)) {
if (imageView.isShown())
if (msg.obj != null) {
imageView.setBackgroundDrawable((Drawable) msg.obj);
} else {
// imageView.setImageDrawable(placeholder);
imageView.setBackgroundDrawable(placeholder);
// Log.d(null, "fail " + url);
}
}
}
};
mThreadPool.submit(new Runnable() {
@Override
public void run() {
final Drawable bmp = downloadDrawable(url);
// if the view is not visible anymore, the image will be ready
// for next time in cache
if (imageView.isShown()) {
Message message = Message.obtain();
message.obj = bmp;
// Log.d(null, "Item downloaded: " + url);
handler.sendMessage(message);
}
}
});
}
private Drawable downloadDrawable(String url) {
try {
InputStream is = getInputStream(url);
Drawable drawable = Drawable.createFromStream(is, url);
putDrawableInCache(url, drawable);
return drawable;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private InputStream getInputStream(String urlString)
throws MalformedURLException, IOException {
URL url = new URL(urlString);
URLConnection connection;
connection = url.openConnection();
connection.setUseCaches(true);
connection.connect();
InputStream response = connection.getInputStream();
return response;
}
}
我正在通过以下方式将图像设置为 ListView 项目:
imageDownloader.loadDrawable(EventsListActivity.stylesheet.getBaseurl()+""+speaker.getPhoto(), imageView, mContext.getResources().getDrawable( R.drawable.noimage ));