2011-03-21 48 views
7

Tôi hiểu rằng câu hỏi này được hỏi vài lần. Không ai trong số họ là rõ ràng về giải pháp. Hãy để tôi giải thích vấn đề.Kích thước bitmap lỗi outofmemory của Android vượt quá ngân sách vm trong 2.3.3

  1. Tôi có Hoạt động tải 4 hình ảnh cùng một lúc.
  2. Tôi tải hình ảnh trong phương thức onResume().
  3. Hoạt động ném lỗi bitmap khi tải.

Ghi chú.

  1. Tôi đang đặt hình ảnh bằng cách sử dụng gọi hàm setImageResource (R.drawable.xxxx) chứ không phải trực tiếp bitmap/drawables.
  2. Hình ảnh được chia tỷ lệ chính xác.
  3. Activtiy WORKS FINE trong tất cả các trình giả lập trước 2.3 và ĐANG LÀM VIỆC trong thiết bị thực tế (Samsung Galaxy 5)
  4. Lỗi xuất hiện khi khởi tạo đầu tiên và không có sự kiện thay đổi định hướng nào được kích hoạt. Hình ảnh
  5. có kích thước 800 x 600 và kích thước trung bình là 15kb (mỗi kích thước).

Hãy cho tôi biết bất kỳ giải pháp nào. Ngoài ra, hãy cho tôi biết nếu bạn có vấn đề tương tự với trình mô phỏng Android 2.3.3.

[cập nhật] -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)

Cảm ơn. Được quản lý để giải quyết nó. Chia sẻ mã vì lợi ích của người khác Lớp tùy chỉnh đã giải quyết vấn đề này. dựa trên liên kết @ 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

bài đang onResume của bạn, và nó có thể được dễ dàng hơn để giúp bạn. –

Trả lời

3

Bitmap tiêu thụ rất nhiều không gian bộ nhớ. không tạo biến bitmap mới cho tất cả hình ảnh bạn tải về hoạt động, thay vào đó bạn có thể tạo một biến bitmap và sử dụng lại chúng nhiều nhất có thể.

bạn có thể sử dụng đoạn mã này để thay đổi kích thước bitmap

http://pastebin.com/D8vbQd2u

+0

Tôi có cần xử lý việc này vì tôi không sử dụng biến bitmap không? Tôi sử dụng biểu mẫu tham chiếu có thể vẽ trực tiếp. mã được đính kèm. – GSree

+0

bạn không cần phải xem xét thay đổi kích thước cho hình ảnh nhỏ nhưng 64KB trên một hoạt động sẽ nhấn mạnh giao diện người dùng và tiêu thụ bộ nhớ. chuyển đổi chúng thành bitmap và cung cấp chúng cho imageview – Jana

+0

rdhanan.S 64kb là gì? Có kích thước hình ảnh cho mỗi hoạt động hay không. Hình ảnh của tôi có kích thước ~ 15kb ở định dạng png. Một hoạt động sẽ có 4 hình ảnh. Vì vậy, ~ 15 x 4 = ~ 60Kb. – GSree

0

Bạn có thể đăng đoạn mã của ngăn xếp Activity + hay không.

Bạn đã kiểm tra Avoiding memory leaks article chưa?

Đặc biệt là các phần sau:

Khi một drawable được gắn vào một cái nhìn, quan điểm được thiết lập như một callback trên drawable. Trong đoạn mã ở trên, điều này có nghĩa là drawable có tham chiếu đến TextView mà chính nó có tham chiếu đến hoạt động (Context) mà lần lượt có tham chiếu đến khá nhiều thứ (tùy thuộc vào mã của bạn.)

+0

Tôi đã kiểm tra liên kết. Không chắc chắn nếu có nhiều tôi có thể làm với mã của tôi. Đã cập nhật đoạn mã cho câu hỏi. Vui lòng kiểm tra và cho tôi biết nếu tôi cần thực hiện một số sửa đổi dựa trên điều này. Hình ảnh – GSree

0

dường như những hình ảnh này rất nặng nề. Tôi khuyên bạn nên khởi động AsyncTimer mà thực sự trả về thể hiện bitmap và trong doBackground() của AsyncTask chuyển id hình ảnh và rescale nó đến kích thước mong muốn nói 32 x 32 sử dụng phương thức createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter) của lớp Bitmap.

+0

có kích thước 800 x 600 và kích thước trung bình là 15kb (mỗi hình). Bạn có thể đăng một số đoạn mã về cách thực hiện AsyncTimer không? – GSree

Các vấn đề liên quan