2013-02-28 60 views
1

我開發Android這是應該採取從相機拍攝的照片,並使用這些圖片爲資料圖片爲應用程序的應用程序後崩潰。不過,該應用運行良好的前3-4圖片,但是當我嘗試拍攝更多的照片時,應用程序會崩潰。原因是內存泄漏。應用採取多張圖片從Android攝像頭

這裏是相機的開始意圖的代碼:

String fileName = "temp.jpg"; 
ContentValues values = new ContentValues(); 
values.put(MediaStore.Images.Media.TITLE, fileName); 
mCapturedImageURI = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); 
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
takePictureIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); 
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedImageURI); 
startActivityForResult(takePictureIntent,RESULT_LOAD_IMAGE_CAMERA); 

這裏是用於接收的意圖的代碼:

if (requestCode == RESULT_LOAD_IMAGE_CAMERA && resultCode == RESULT_OK) { 
    String[] projection = { MediaStore.Images.Media.DATA}; 
    Cursor cursor = managedQuery(mCapturedImageURI, projection, null, null, null); 
    final int column_index_data = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); 
    cursor.moveToFirst(); 
    String capturedImageFilePath = cursor.getString(column_index_data); 
    profilePic.setImageURI(Uri.fromFile(new File(capturedImageFilePath))); 
} 

這裏是日誌:

02-28 18:28:36.727: E/dalvikvm-heap(4081): 9830400-byte external allocation too large for this process. 
02-28 18:28:36.727: E/GraphicsJNI(4081): VM won't let us allocate 9830400 bytes 
02-28 18:28:36.824: E/AndroidRuntime(4081): FATAL EXCEPTION: main 
02-28 18:28:36.824: E/AndroidRuntime(4081): java.lang.OutOfMemoryError: bitmap size exceeds VM budget 
02-28 18:28:36.824: E/AndroidRuntime(4081):  at android.graphics.BitmapFactory.nativeDecodeStream(Native Method) 
02-28 18:28:36.824: E/AndroidRuntime(4081):  at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:562) 
02-28 18:28:36.824: E/AndroidRuntime(4081):  at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:426) 
02-28 18:28:36.824: E/AndroidRuntime(4081):  at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697) 
02-28 18:28:36.824: E/AndroidRuntime(4081):  at android.graphics.drawable.Drawable.createFromStream(Drawable.java:657) 
02-28 18:28:36.824: E/AndroidRuntime(4081):  at android.widget.ImageView.resolveUri(ImageView.java:509) 
02-28 18:28:36.824: E/AndroidRuntime(4081):  at android.widget.ImageView.setImageURI(ImageView.java:293) 
02-28 18:28:36.824: E/AndroidRuntime(4081):  at com.octanetech.cortes.ProfileActivity.onActivityResult(ProfileActivity.java:596) 
02-28 18:28:36.824: E/AndroidRuntime(4081):  at android.app.Activity.dispatchActivityResult(Activity.java:3890) 
02-28 18:28:36.824: E/AndroidRuntime(4081):  at android.app.ActivityThread.deliverResults(ActivityThread.java:3511) 
02-28 18:28:36.824: E/AndroidRuntime(4081):  at android.app.ActivityThread.handleSendResult(ActivityThread.java:3557) 
02-28 18:28:36.824: E/AndroidRuntime(4081):  at android.app.ActivityThread.access$2800(ActivityThread.java:125) 
02-28 18:28:36.824: E/AndroidRuntime(4081):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2063) 
02-28 18:28:36.824: E/AndroidRuntime(4081):  at android.os.Handler.dispatchMessage(Handler.java:99) 
02-28 18:28:36.824: E/AndroidRuntime(4081):  at android.os.Looper.loop(Looper.java:123) 
02-28 18:28:36.824: E/AndroidRuntime(4081):  at android.app.ActivityThread.main(ActivityThread.java:4627) 
02-28 18:28:36.824: E/AndroidRuntime(4081):  at java.lang.reflect.Method.invokeNative(Native Method) 
02-28 18:28:36.824: E/AndroidRuntime(4081):  at java.lang.reflect.Method.invoke(Method.java:521) 
02-28 18:28:36.824: E/AndroidRuntime(4081):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:871) 
02-28 18:28:36.824: E/AndroidRuntime(4081):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629) 
02-28 18:28:36.824: E/AndroidRuntime(4081):  at dalvik.system.NativeStart.main(Native Method) 

不限幫助將不勝感激。

+0

你有機會閱讀這個嗎? http://stackoverflow.com/questions/4511057/android-out-of-memory-on-image-capture – appsroxcom 2013-02-28 14:02:02

回答

3

最後我解決了自己的問題。導致內存泄漏的主要問題是我不是回收位圖對象。我只是替換位圖對象與另一個位圖圖像。認爲該對象被另一個位圖圖像替換,仍然存在於內存中的前一個位圖圖像。因此,在從相機拍攝多張圖像時,位圖圖像堆積並引發了內存不足的情況。

因此,我起了特技Bitmap對象分配新圖像之前回收(刪除)位圖圖像。 我只是用

mImageBitmap.recycle(); 

這沖走先前的位圖圖像,沒有發生內存泄漏。希望它也能幫助其他人。

3

替換該行

profilePic.setImageURI(Uri.fromFile(new File(capturedImageFilePath))); 

您直接加載圖像的SD卡,它可以在尺寸上大,造成內存不足的問題。

試試這個

BitmapFactory.Options options = new BitmapFactory.Options(); 
options.inSampleSize=8;  // 1/8 of original image 
Bitmap b = BitmapFactory.decodeFile(capturedImageFilePath,options); 
profilePic.setImageBitmap(b); 
+0

感謝您的答覆。我並不關心內存的大小,我更擔心的是內存泄漏正在發生。不知怎的,相機捕獲的圖像在垃圾回收中沒有被移除。它被存儲在應用程序的內存中。我們可以按照這種方法,但它只會將我的應用程序的崩潰延遲8次,而不會完全阻止它。 – 2013-03-01 05:21:27

0

請嘗試按比例使用inSampleSize如下的較大的位圖:從@費多爾的懶列表採取 片段 https://github.com/thest1/LazyList/blob/master/src/com/fedorvlasov/lazylist/ImageLoader.java

公衆詮釋inSampleSize

如果設置爲值> 1,請求解碼器對原始圖像進行二次採樣,返回較小的圖像以節省存儲空間。

//decodes image and scales it to reduce memory consumption 
    private Bitmap decodeFile(File f){ 
     try { 
      //decode image size 
      BitmapFactory.Options o = new BitmapFactory.Options(); 
      o.inJustDecodeBounds = true; 
      FileInputStream stream1=new FileInputStream(f); 
      BitmapFactory.decodeStream(stream1,null,o); 
      stream1.close(); 

      //Find the correct scale value. It should be the power of 2. 
      final int REQUIRED_SIZE=70; 
      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; 
      FileInputStream stream2=new FileInputStream(f); 
      Bitmap bitmap=BitmapFactory.decodeStream(stream2, null, o2); 
      stream2.close(); 
      return bitmap; 
     } catch (FileNotFoundException e) { 
     } 
     catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 

希望這有助於你:

+0

感謝您的回覆。我並不關心內存的大小,我更擔心的是內存泄漏正在發生。不知怎的,相機捕獲的圖像在垃圾回收中沒有被移除。它被存儲在應用程序的內存中。我們可以按照這種方法,但它只會延遲我的應用程序的崩潰,而不會完全阻止它。 – 2013-03-01 05:22:48

相關問題