Universal image loader遇到OOM
阿新 • • 發佈:2019-01-10
Universal image loader應該不用介紹了,大家應該都很熟悉了,但是近來在使用時候遇到了OOM,呼叫棧如下:
07-24 13:01:24.876 31362 31362 E AndroidRuntime: java.lang.OutOfMemoryError 07-24 13:01:24.876 31362 31362 E AndroidRuntime: at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method) 07-24 13:01:24.876 31362 31362 E AndroidRuntime: at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:594) 07-24 13:01:24.876 31362 31362 E AndroidRuntime: at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:429) 07-24 13:01:24.876 31362 31362 E AndroidRuntime: at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:840) 07-24 13:01:24.876 31362 31362 E AndroidRuntime: at android.content.res.Resources.loadDrawable(Resources.java:2110) 07-24 13:01:24.876 31362 31362 E AndroidRuntime: at android.content.res.Resources.getDrawable(Resources.java:700) 07-24 13:01:24.876 31362 31362 E AndroidRuntime: at com.nostra13.universalimageloader.core.DisplayImageOptions.getImageOnFail(DisplayImageOptions.java:142) 07-24 13:01:24.876 31362 31362 E AndroidRuntime: at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask$2.run(LoadAndDisplayImageTask.java:348) 07-24 13:01:24.876 31362 31362 E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:733) 07-24 13:01:24.876 31362 31362 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:95) 07-24 13:01:24.876 31362 31362 E AndroidRuntime: at android.os.Looper.loop(Looper.java:136) 07-24 13:01:24.876 31362 31362 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5001) 07-24 13:01:24.876 31362 31362 E AndroidRuntime: at java.lang.reflect.Method.invokeNative(Native Method) 07-24 13:01:24.876 31362 31362 E AndroidRuntime: at java.lang.reflect.Method.invoke(Method.java:515) 07-24 13:01:24.876 31362 31362 E AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:815) 07-24 13:01:24.876 31362 31362 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:631) 07-24 13:01:24.876 31362 31362 E AndroidRuntime: at dalvik.system.NativeStart.main(Native Method)
然後在網上查了一些資料,主要解決辦法如下:
1. 減少執行緒池中執行緒的個數。在ImageLoaderConfiguration的.threadPoolSize中配置,推薦1-5.
2. 使用Bitmap.Config.RGB555代替Bitmap.Config.ARGB8888,減少記憶體佔用。在DisplayImageOptions的.bitmapConfig中配置
3. 在ImageLoaderConfiguration中配置圖片快取策略為.memoryCache(new WeakMemoryCache())
4. 在DisplayImageOption中配置imageScaleType(ImageScaleType.IN_SAMPLE_INT)或是imageScaleType(ImageScaleType.EXACTY)
使用了上述4中方法,但是還是會遇到OOM,後來仔細分析下呼叫棧,發現是在對本地的圖片資源進行解碼時報出了OOM,那就取消配置showImageOnLoading和showImageOnFail,直接在ImageLoadingListener中setImageResource,這樣就不會再出現OOM了。
至於原因,初步判斷是Universal Image loader會對本地圖片資源進行解碼,但是android系統已經對本地的圖片資源解碼過了,所以會額外佔用記憶體,從而使得報出OOM。