2012-08-16 58 views
-8

Possible Duplicate:
java.lang.OutOfMemoryError: bitmap size exceeds VM budget - Android安卓:java.lang.OutOfMemoryError:位圖大小超過VM預算

我目前正在開發一款Android應用,顯示從URL中下載的圖像,並把它們放在一個ListView。當它被點擊時,創建一個新的圖像點擊圖像。當點擊較小的圖像(7kb)時,它運行良好。即使運行良好達200kb。但是任何比這更大的東西,我會收到一個錯誤:「應用程序意外停止,請重試。」看看LogCat,看起來問題與Android內存不足有關。有針對這個的解決方法嗎?還是隻是將我的圖像分辨率降低到200kb的範圍?當然,圖像大小不應該高達1或2兆字節?加載可能需要更長的時間,但不明白爲什麼會引發錯誤。

任何幫助將不勝感激!

Zoom.java

public class Zoom extends Activity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     requestWindowFeature(Window.FEATURE_NO_TITLE); 
     getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN); 
     setContentView(R.layout.gallery_zoom); 

     String selection = getIntent().getExtras().getString("image"); 
     Toast.makeText(this, selection, Toast.LENGTH_LONG).show(); 

     new backgroundLoader().execute(); 
    } 


    public class backgroundLoader extends AsyncTask<Void, Void, Void> { 
     Bitmap bmp; 

     @Override 
     protected Void doInBackground(Void... params) { 
      BitmapFactory.Options bmpOptions; 
      bmpOptions = new BitmapFactory.Options(); 
      bmpOptions.inSampleSize = 1; 
      bmp = LoadImage(getIntent().getExtras().getString("image"), bmpOptions); 
      return null; 
     } 

     @Override 
     protected void onPostExecute(Void result) { 
      ImageView image = (ImageView) findViewById(R.id.imageZoom); 
      image.setImageBitmap(bmp); 
      super.onPostExecute(result); 
     } 

    } 

    private Bitmap LoadImage(String URL, BitmapFactory.Options options) { 
     Bitmap bitmap = null; 
     InputStream in = null; 
     try { 
      in = OpenHttpConnection(URL); 
      bitmap = BitmapFactory.decodeStream(in, null, options); 
      in.close(); 
     } catch (IOException e1) { 
     } 
     return bitmap; 

    } 

    private InputStream OpenHttpConnection(String strURL) throws IOException { 
     InputStream inputStream = null; 
     URL url = new URL(strURL); 

     HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 
     try { 
      InputStream in = new BufferedInputStream(connection.getInputStream()); 
      return in; 
     } catch (Exception exception) { 
      exception.printStackTrace(); 
      return null; 
     } 
    } 

} 

logcat的日誌

08-13 07:35:01.798: E/dalvikvm-heap(1132): 48064000-byte external allocation too large for this process. 
08-13 07:35:01.888: E/GraphicsJNI(1132): VM won't let us allocate 48064000 bytes 
08-13 07:35:01.888: D/dalvikvm(1132): GC_FOR_MALLOC freed 1K, 54% free 2694K/5831K, external 2229K/3423K, paused 19ms 
08-13 07:35:01.888: D/skia(1132): --- decoder->decode returned false 
08-13 07:35:01.888: W/dalvikvm(1132): threadid=14: thread exiting with uncaught exception (group=0x40015560) 
08-13 07:35:01.898: E/AndroidRuntime(1132): FATAL EXCEPTION: AsyncTask #1 
08-13 07:35:01.898: E/AndroidRuntime(1132): java.lang.RuntimeException: An error occured while executing doInBackground() 
08-13 07:35:01.898: E/AndroidRuntime(1132):  at android.os.AsyncTask$3.done(AsyncTask.java:200) 
08-13 07:35:01.898: E/AndroidRuntime(1132):  at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274) 
08-13 07:35:01.898: E/AndroidRuntime(1132):  at java.util.concurrent.FutureTask.setException(FutureTask.java:125) 
08-13 07:35:01.898: E/AndroidRuntime(1132):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308) 
08-13 07:35:01.898: E/AndroidRuntime(1132):  at java.util.concurrent.FutureTask.run(FutureTask.java:138) 
08-13 07:35:01.898: E/AndroidRuntime(1132):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088) 
08-13 07:35:01.898: E/AndroidRuntime(1132):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581) 
08-13 07:35:01.898: E/AndroidRuntime(1132):  at java.lang.Thread.run(Thread.java:1019) 
08-13 07:35:01.898: E/AndroidRuntime(1132): Caused by: java.lang.OutOfMemoryError: bitmap size exceeds VM budget 
08-13 07:35:01.898: E/AndroidRuntime(1132):  at android.graphics.BitmapFactory.nativeDecodeStream(Native Method) 
08-13 07:35:01.898: E/AndroidRuntime(1132):  at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:470) 
08-13 07:35:01.898: E/AndroidRuntime(1132):  at com.example.example.mobile.application.gallery.Zoom.LoadImage(Zoom.java:72) 
08-13 07:35:01.898: E/AndroidRuntime(1132):  at com.example.example.mobile.application.gallery.Zoom.access$0(Zoom.java:67) 
08-13 07:35:01.898: E/AndroidRuntime(1132):  at com.example.example.mobile.application.gallery.Zoom$backgroundLoader.doInBackground(Zoom.java:54) 
08-13 07:35:01.898: E/AndroidRuntime(1132):  at com.example.example.mobile.application.gallery.Zoom$backgroundLoader.doInBackground(Zoom.java:1) 
08-13 07:35:01.898: E/AndroidRuntime(1132):  at android.os.AsyncTask$2.call(AsyncTask.java:185) 
08-13 07:35:01.898: E/AndroidRuntime(1132):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306) 
08-13 07:35:01.898: E/AndroidRuntime(1132):  ... 4 more 
08-13 07:35:01.908: W/ActivityManager(61): Force finishing activity com.example.example.mobile.application/.gallery.Zoom 
+3

本頁右側的「相關」欄目沒有幫助? – 2012-08-16 10:48:05

+0

看起來你想加載一個45MB的圖片...這將無法在許多手機上工作 – IncrediApp 2012-08-16 10:48:41

+0

看看這個 http:// stackoverflow。com/questions/1949066/java-lang-outofmemoryerror -bitmap-size-exceed-vm-budget-android – 2012-08-16 10:50:24

回答

1

首先你要知道你的200KB是一個壓縮jpg格式。 Android將圖像以非壓縮格式的位圖存儲。根據照片的大小,每張照片最多可以添加幾兆字節。

要儘量減少這個問題,你可以看看在BitmapFacotry insamplesize方法:

http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html#inSampleSize

它可以讓你打開一個圖像,但在一個較低的分辨率(由兩個大國)。

也儘量agressively電話:

mybitmap = null; 
System.gc; 
System.runFinalization; 
System.gc; 

每一次就可以了。

1

的幾點思考

  1. 參考不要把位圖內的AsyncTask,通過定義位圖作爲PARAM,不能太虛正確地使用它。研究here

  2. 您可能需要回收位圖。有關如何處理位圖的信息,請參閱Android開發人員培訓here

  3. 學習記憶分析工具(MAT)here

相關問題