2011-03-21 81 views
7

我知道這個問題被問幾次。這些解決方案中沒有一個是清楚的。讓我解釋一下這個問題。Android outofmemory錯誤位圖大小超過vm 2.3.3中的預算

  1. 我有一個活動,一次加載4個圖像。
  2. 我在onResume()方法中加載圖像。
  3. 加載時,Activity拋出位圖錯誤。

注意事項。

  1. 我使用setImageResource(R.drawable.xxxx)方法調用設置圖像,而不是直接繪製位圖。
  2. 圖像正確縮放。
  3. 活動在2.3之前的所有仿真器中工作良好,並且在實際設備(Samsung Galaxy 5)中工作得很好
  4. 錯誤出現在第一次初始化時,並且未激發方向更改事件。
  5. 圖片尺寸爲800 x 600,平均大小爲15kb(每個)。

讓我知道任何解決方案。另外讓我知道你是否有類似的問題與Android 2.3.3模擬器。

[更新] -snippets

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
      ... 
    img_topLeft = (ImageView) findViewById(R.id.Img_Alph_Q_TopLeft); 
    img_topRight = (ImageView) findViewById(R.id.Img_Alph_Q_TopRight); 
    img_bottomLeft = (ImageView) findViewById(R.id.Img_Alph_Q_BottomLeft); 
    img_bottomRight = (ImageView) findViewById(R.id.Img_Alph_Q_BottomRight); 
    ... 
    } 
protected void onResume() { 
    super.onResume(); 
      img_topLeft.setImageResource(R.drawable.xxx); 
      img_topRight.setImageResource(R.drawable.xxx); 
      img_bottomLeft.setImageResource(R.drawable.xxx); 
      img_bottomRight.setImageResource(R.drawable.xxx); 
    ... 
    } 

03-21 08:59:17.362: ERROR/dalvikvm-heap(5883): 4320000-byte external allocation too large for this process. 03-21 08:59:17.412: ERROR/GraphicsJNI(5883): VM won't let us allocate 4320000 bytes 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): FATAL EXCEPTION: main 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): java.lang.OutOfMemoryError: bitmap size exceeds VM budget 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.graphics.Bitmap.nativeCreate(Native Method) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.graphics.Bitmap.createBitmap(Bitmap.java:477) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.graphics.Bitmap.createBitmap(Bitmap.java:444) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:349) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.graphics.BitmapFactory.finishDecode(BitmapFactory.java:498) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:473) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:336) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.content.res.Resources.loadDrawable(Resources.java:1709) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.content.res.Resources.getDrawable(Resources.java:581) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.widget.ImageView.resolveUri(ImageView.java:501) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.widget.ImageView.setImageResource(ImageView.java:280) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at Quiz.java:124) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): Quiz.onResume(Quiz.java:92) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1150) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.app.Activity.performResume(Activity.java:3832) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2110) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2135) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1668) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.app.ActivityThread.access$1500(ActivityThread.java:117) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.os.Handler.dispatchMessage(Handler.java:99) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.os.Looper.loop(Looper.java:123) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at android.app.ActivityThread.main(ActivityThread.java:3683) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at java.lang.reflect.Method.invokeNative(Native Method) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at java.lang.reflect.Method.invoke(Method.java:507) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 03-21 08:59:17.432: ERROR/AndroidRuntime(5883): at dalvik.system.NativeStart.main(Native Method)

感謝。管理解決它。共享代碼以利於他人 解決此問題的自定義類。基於@ Janardhanan.S鏈接。

public class BitmapResizer { 

public static Bitmap decodeImage(Resources res, int id ,int requiredSize){ 
    try { 
     BitmapFactory.Options o = new BitmapFactory.Options(); 
     o.inJustDecodeBounds = true; 
     BitmapFactory.decodeResource(res, id, o); 

     //Find the correct scale value. It should be the power of 2. 
     final int REQUIRED_SIZE=requiredSize; 
     int width_tmp=o.outWidth, height_tmp=o.outHeight; 
     int scale=1; 
     while(true){ 
      if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE) 
       break; 
      width_tmp/=2; 
      height_tmp/=2; 
      scale*=2; 
     } 

     //decode with inSampleSize 
     BitmapFactory.Options o2 = new BitmapFactory.Options(); 
     o2.inSampleSize=scale; 
     return BitmapFactory.decodeResource(res, id, o2); 
    } catch (Exception e) { 

    } 
    return null; 
} 

} 

//Class call 
int requiredsize = 100; // Still playing around with this number to find the optimum value 
img_topLeft.setImageBitmap(BitmapResizer.decodeImage(getResources(), 
     AlphResourceSet.R.drawable.xxx, requiredsize)); 
+0

安置自己的onResume代碼,它可能是更容易幫助你。 – 2011-03-21 08:10:52

回答

3

位圖消耗大量內存空間。 不要爲您在活動上加載的所有圖像創建新的位圖變量,而是可以創建一個位圖變量並儘可能多地重用它們。

您可以使用此代碼段來調整位圖

http://pastebin.com/D8vbQd2u

+0

考慮到我沒有使用位圖變量,我需要處理嗎?我直接使用可繪製的參考表單。代碼附加。 – GSree 2011-03-21 09:30:48

+0

你不需要考慮調整小圖像的大小,但是一個活動的64KB會壓縮UI並消耗內存。 將它們轉換爲位圖並將它們送入imageview – Jana 2011-03-21 09:54:43

+0

rdhanan.S什麼是64kb?是否有每個活動的圖像大小。我的圖片大小爲15kb,格式爲png。一項活動將有4張圖片。所以〜15×4 =〜60Kb。 – GSree 2011-03-21 10:04:53

0

您可以發佈Activity + stacktrace的代碼片段。

您是否已經檢查了Avoiding memory leaks article

特別是以下部分:

當繪製對象被附接到一個視圖,該視圖被設置爲在可繪製的回調。在上面的代碼片段中,這意味着drawable對TextView有一個引用,它本身對活動(Context)有一個引用,它依次引用任何東西(取決於你的代碼)。

+0

我檢查了鏈接。不知道我的代碼能做多少。更新了問題的代碼片段。請檢查並告訴我是否需要根據此進行一些修改。 – GSree 2011-03-21 09:29:46

0

It似乎圖像本質上是非常重的。我建議啓動實際返回位圖實例的AsyncTimer,並在AsyncTask的doBackground()中傳遞圖像ID,並使用createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter)方法將Bitmap類的方法重新調整爲想要的大小,例如32 x 32。

+0

圖片尺寸爲800 x 600,平均大小爲15kb(每個)。你能發表一些關於如何做AsyncTimer的片段嗎? – GSree 2011-03-21 09:32:53

相關問題