2012-10-24 59 views
6

我正在使用對話框在我的android項目中顯示圖像。第一個可以打開,但是當我關閉它並再次執行該過程以顯示另一個時,應用程序會因爲內存錯誤而崩潰(它運行在三星Galaxy S3上 - 所以不應該成爲問題)。顯示照片內存不足

錯誤:

10-24 11:25:45.575: E/dalvikvm-heap(29194): Out of memory on a 31961104-byte allocation. 
10-24 11:25:45.580: E/AndroidRuntime(29194): FATAL EXCEPTION: main 
10-24 11:25:45.580: E/AndroidRuntime(29194): java.lang.OutOfMemoryError 
10-24 11:25:45.580: E/AndroidRuntime(29194): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:587) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:389) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:418) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at android.graphics.drawable.Drawable.createFromPath(Drawable.java:882) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at android.widget.ImageView.resolveUri(ImageView.java:569) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at android.widget.ImageView.setImageURI(ImageView.java:340) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at com.directenquiries.assessment.tool.AddAsset.loadPhoto(AddAsset.java:771) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at com.directenquiries.assessment.tool.AddAsset$11.onClick(AddAsset.java:748) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at com.android.internal.app.AlertController$AlertParams$3.onItemClick(AlertController.java:936) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at android.widget.AdapterView.performItemClick(AdapterView.java:292) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at android.widget.AbsListView.performItemClick(AbsListView.java:1359) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at android.widget.AbsListView$PerformClick.run(AbsListView.java:2988) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at android.widget.AbsListView$1.run(AbsListView.java:3783) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at android.os.Handler.handleCallback(Handler.java:605) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at android.os.Handler.dispatchMessage(Handler.java:92) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at android.os.Looper.loop(Looper.java:137) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at android.app.ActivityThread.main(ActivityThread.java:4517) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at java.lang.reflect.Method.invokeNative(Native Method) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at java.lang.reflect.Method.invoke(Method.java:511) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:993) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:760) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at dalvik.system.NativeStart.main(Native Method) 

加載代碼:

public void loadPhotoList(){ 

    Cursor f = db.rawQuery("select * from stationphotos where StationObjectID = '"+ checkStationObjectID + "'", null); 
    final ArrayList<String> mHelperNames= new ArrayList<String>(); 

      if(f.getCount() != 0) { 
       f.moveToFirst(); 

       f.moveToFirst(); 
       while(!f.isAfterLast()) { 
        mHelperNames.add(f.getString(f.getColumnIndex("FilePath"))); 
        f.moveToNext(); 
       } 
      } 
    f.close(); 
    final String [] nameStrings = new String [mHelperNames.size()]; 

    for(int i=0; i<mHelperNames.size(); i++) 
     nameStrings[i] = mHelperNames.get(i).toString(); 


    AlertDialog.Builder builder = new AlertDialog.Builder(this); 

    builder.setTitle("Select Picture"); 
    builder.setItems(nameStrings, new DialogInterface.OnClickListener() { 

     public void onClick(DialogInterface dialog, int item) { 

      loadPhoto(mHelperNames.get(item).toString()); 

     } 

    }); 

    AlertDialog alert = builder.create(); 

    alert.show(); 

} 


public void loadPhoto(String imagepath){ 

    Dialog dialog = new Dialog(this); 
    dialog.setContentView(R.layout.activity_show_image); 
    dialog.setTitle("Image"); 
    dialog.setCancelable(true); 

    ImageView img = (ImageView) dialog.findViewById(R.id.imageView1); 
    img.setImageResource(R.drawable.ico_partial); 
    Uri imgUri = Uri.parse(imagepath); 
    img.setImageURI(imgUri); 


    dialog.show(); 
} 

編輯:什麼我使用,使其現在的工作:

public static Bitmap decodeSampledBitmapFromFile(String imagePath, int reqWidth, int reqHeight) { 

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

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

    // Decode bitmap with inSampleSize set 
    options.inJustDecodeBounds = false; 
    return BitmapFactory.decodeFile(imagePath, options); 
} 
    public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { 
    // Raw height and width of image 
    final int height = options.outHeight; 
    final int width = options.outWidth; 
    int inSampleSize = 1; 

    if (height > reqHeight || width > reqWidth) { 
     if (width > height) { 
      inSampleSize = Math.round((float)height/(float)reqHeight); 
     } else { 
      inSampleSize = Math.round((float)width/(float)reqWidth); 
     } 
    } 
    return inSampleSize; 
} 



img.setImageBitmap(decodeSampledBitmapFromFile(imagepath, 500, 500)); 
+0

這是什麼內存分析器節目嗎?什麼是堆大小,堆內存空間? – sandrstar

+0

當我載入照片時,堆高達44mb。還有另一種方法可以做到嗎? 1 \t 45.258 MB \t 44.830 MB \t 438.242 KB \t 99.05%\t 57,128 – TMB87

+0

如何知道高度和寬度是500? –

回答

5

我曾經歷過這個,我不知道如果我的回答是最好的做法還是不但是......

這可能是你的問題:

Uri imgUri = Uri.parse(imagepath); 
    img.setImageURI(imgUri); 

Heap shot up to 44mb when I loaded the photo.

如果裝入一個大的圖像,然後你可能會用盡內存。如果在加載一系列圖像時無法使用體面的內存管理,也會耗盡內存。

我用BitmapFactory解碼文件,並使用BitmapFactory.Options創建一個新的標準位圖,然後我在屏幕上顯示。

這個想法是,BitmapFactory.Options可以讓你更好地控制你的圖像可能用到的潛在內存。例如,不需要在甚至不支持這些分辨率的屏幕上以全尺寸顯示1920x1080圖像。

有一些相關的計算器問題可能對您有幫助,特別是:Handling large Bitmaps,它着重於BitmapFactory.Options選項inJustDecodeBounds

最後,我發現這個名爲Aquery的輕量級庫。它有一大堆處理大文件的方法,到目前爲止它做得很好。很值得一看。它在Web開發(因此而得名)方面對JQuery使用了一個類似的範例,並且引入了用於處理Views的更短的語法。他們的文檔交易的以下部分與本地和從遠程源圖像加載,包括退回圖片:

http://code.google.com/p/android-query/wiki/ImageLoading

+0

感謝你,我只是看着位圖工廠,現在我我正在壓縮 – TMB87