2014-07-24 105 views
0

我有一個應用程序有很多頁面,每個人都有自己的圖像,它是從網上加載一個asynctask。問題在於當你打開和關閉很多頁面時,經過一段時間後會導致內存異常錯誤。如何在離開活動時清除內存中的圖像以防止出現這種情況?如何清除內存,以防止java.lang.OutOfMemoryError

的圖像由該加載的AsyncTask:

private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> { 
     ImageView bmImage; 

     public DownloadImageTask(ImageView bmImage) { 
      this.bmImage = bmImage; 
     } 

     protected Bitmap doInBackground(String... urls) { 
      String urldisplay = urls[0]; 
      Bitmap mIcon11 = null; 
      try { 
       InputStream in = new java.net.URL(urldisplay).openStream(); 
       mIcon11 = BitmapFactory.decodeStream(in); 
      } catch (Exception e) { 
       Log.e("Error", e.getMessage()); 
       e.printStackTrace(); 
      } 
      return mIcon11; 
     } 

     protected void onPostExecute(Bitmap result) { 
      bmImage.setImageBitmap(result); 
     } 
    } 

通過調用:

new DownloadImageTask((ImageView) findViewById(R.id.ivCard)).execute("http://myurl.com/example.png"); 

這種活性被打開,並且具有不同的值和不同的圖像關閉。打開此活動的一些情況後,它提供了以下OutOfMemory錯誤:

07-24 16:37:57.870 27717-28014/com.yigitserin.hsboard E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1 
    java.lang.RuntimeException: An error occured while executing doInBackground() 
      at android.os.AsyncTask$3.done(AsyncTask.java:299) 
      at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273) 
      at java.util.concurrent.FutureTask.setException(FutureTask.java:124) 
      at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307) 
      at java.util.concurrent.FutureTask.run(FutureTask.java:137) 
      at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230) 
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) 
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) 
      at java.lang.Thread.run(Thread.java:856) 
    Caused by: java.lang.OutOfMemoryError 
      at android.graphics.BitmapFactory.nativeDecodeStream(Native Method) 
      at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:650) 
      at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:722) 
      at com.yigitserin.hsboard.HeroActivity$DownloadImageTask.doInBackground(HeroActivity.java:137) 
      at com.yigitserin.hsboard.HeroActivity$DownloadImageTask.doInBackground(HeroActivity.java:125) 
      at android.os.AsyncTask$2.call(AsyncTask.java:287) 
      at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 
            at java.util.concurrent.FutureTask.run(FutureTask.java:137) 
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230) 
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) 
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) 
            at java.lang.Thread.run(Thread.java:856) 

如何從存儲在用戶退出本次活動的一個實例後刪除圖像?

回答

0

我想你應該關閉在finally塊流,然後給出一個try.i希望這可以排除一個可能性,那麼我們可以考慮其他的優化技術。

0

您可能不需要「清除」內存,而是對正在加載的Bitmap進行降採樣以避免內存不足異常。關於如何處理和加載大型位圖文件,有一些good tutorials。例如:

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, 
    int reqWidth, int reqHeight) { 

// First decode with inJustDecodeBounds=true to check dimensions 
final BitmapFactory.Options options = new BitmapFactory.Options(); 
options.inJustDecodeBounds = true; 
BitmapFactory.decodeResource(res, resId, options); 

// Calculate inSampleSize 
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); 

// Decode bitmap with inSampleSize set 
options.inJustDecodeBounds = false; 
return BitmapFactory.decodeResource(res, resId, options); 
} 

這裏不是加載整個位圖,而是在加載到內存之前縮小圖像並完全避免這個問題。

如果您仍然遇到問題,我會很快關注爲什麼您有一個應用程序保留對大量不再使用的圖像的引用。當頁面被破壞時,如果你的應用程序設置正確,位圖應該像其他任何東西一樣被垃圾收集。