2013-03-10 14 views
1

我正在打開圖像,使用它並保存的項目中工作。圖像可以是一個非常龐大的圖像,就像一個攝像頭PIC,所以我做的幾件事情,以確保沒有得到OutOfMemory異常(基本上是出現在這裏http://developer.android.com/training/displaying-bitmaps/load-bitmap.html):在單獨的線程中使用位圖

  • 執行的寬度和高度的所有測量圖像而無需實際打開它,使用:
BitmapFactory.Options options = new BitmapFactory.Options(); 
options.inJustDecodeBounds = true; 
BitmapFactory.decodeFile(image_path, options); 
  • 打開圖像已經調整(inSampleSize)和全光照除Bitmap.Config.ARGB_8888(每像素4B)外,還包括每像素2B(每像素2B)。

  • 使用臨時文件在內存中沒有很多的位圖(實際上我只有一個大部分的情況下,應用掩碼時最多2個左右)。

  • 每回收其位圖使用

  • 後,當顯示在ImageView結果,打開它已經擴展到了屏幕尺寸。

但是,在某些情況下,這是不可能只有一個位圖加載在同一時間做了一定的工作(旋轉圖像,微調調整大小,敷面膜,...),而且大多在中等範圍或舊設備,我得到一個OutOfMemory異常

我已經開始添加的所有圖片在後臺作業正與類似下面的(好吧,我是新手):

ProgressDialog dialog = ProgressDialog.show(this, null, "Please wait", true, false); 
new Thread(new BackgroundJob(this, new Runnable() { 
    public void run() { 
     ImageHelper.ImageManipulation(image_path); 
    } 
}, dialog, new Handler())).start(); 

我希望得到一個完全免費的記憶空間與這個新的線程執行那裏的圖像處理任務,但我發現應用程序崩潰在相同的點出於同樣的原因。線程創建爲一個子進程(好),但共享最大堆和當前使用的內存...

有沒有辦法打開一個線程來執行圖像處理有更多的內存工作(釋放內存使用例如活動本身,因爲它是另一個線程)?

非常感謝。

回答

2

有很多,當涉及到Android設備上的內存管理的疑難雜症的 - 尤其是當你在不同的設備進入混合拋出。去年,我在使用不同的Android應用程序玩內存管理方面浪費了一些時間,直到我發現Android-BitmapCache project,我取得了一些重大進展。

我建議大家對Android內存管理感興趣的人到download and inspect Android-BitmapCache project,因爲它包含了一些很棒的代碼 - 所以做爲第一步。

我建議你的第二步大多是看Google I/O: Memory Management for Android Apps,這樣你就可以開始測試你的應用程序正在使用什麼內存,並跟蹤在哪裏開始增加內存使用量。說到這一點 - 我不明白你爲什麼認爲你會「用新線程完全釋放內存空間」 - 你從Android應用中產生的所有線程都將處於相同的進程中,因此無論哪個確切線程在內存使用方面正在運行一些任務。

最後,您可以通過使用android:largeHeap="true"來解決臨時問題,但我認爲您絕對應該瞄準更強大的解決方案。請記住,在某些設備上,您的應用可能無法正常工作(24MB堆,而您想要加載3000x3000的圖片),但應用您可以在project I've linked中找到的所有最佳做法,我相信你會更好關閉。

+1

謝謝你的解釋!我會檢查這個項目和那個談話......我對處理這些內存問題感興趣。關於_largeHeap_,我已放置它,但沒有看到任何區別。關於「完全無記憶」的事情是關於我身邊的誤解:我認爲我可以打開另一個線程,而不是繼承當前的流程消耗...但是因爲它是一個孩子... – Xavi 2013-03-10 12:35:27

+0

@Xavi很高興我能幫助,並隨時提出更多問題 - 只要答案幫助你標記它。至於largeHeap - 這個屬性是在Android 3.0中引入的,因此如果你的設備較舊 - 對於他們你需要[使用VMRuntime](http://stackoverflow.com/a/15010854/237858)。 – kape123 2013-03-12 03:54:21