我對Android開發相當陌生,似乎無法掌握Java內存異常。我知道這意味着我的應用程序已經超出了虛擬機的預算,但經過Google多次搜索之後,我似乎仍然無法理解這一概念。恐怕我的應用使用了太多內存,因爲每個屏幕有六個按鈕選擇器,每個選擇器有兩個位圖,根據屬性選項卡,每個選擇器大約20 kb。在我根深蒂固的G2x上,我將虛擬機預算設置爲12MB,重新啓動手機並運行我的應用程序,無任何問題。我在每個onDestroy()上解綁定drawables,暗示GC也在這裏運行。在模擬器中使用該應用程序一段時間後,我在DDMS屏幕上單擊「原因GC」,結果爲 ID = 1,堆大小6.133 MB,分配2.895MB,免費3.238 MB,%使用47.20,#對象52,623。Android瞭解堆大小
這是我不明白髮生了什麼,我的模擬器設置爲24MB的虛擬機。那個號碼在哪裏?我遇到的實際問題是如果我將模擬器設置爲16MB的虛擬機,那麼我的應用程序會在第二個活動出現內存不足異常時崩潰。爲什麼它不會在VM設置爲12 MB的情況下在我的手機上崩潰,或者在帶有12 MB VM的舊HTC Magic手機上崩潰?你們也認爲我的應用佔用了太多的內存嗎?我不知道這些DDMS數字是否好。謝謝你的時間。
至於我的代碼,我已經在XML佈局中指定了每個圖像,除了向它們添加偵聽器之外,我不會對它們進行編程。我發現這段代碼在這裏,我已經將其添加到我的每一次活動......
@Override
protected void onDestroy() {
super.onDestroy();
unbindDrawables(findViewById(R.id.myRootLayout));
System.gc();
}
private void unbindDrawables(View view) {
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup && !(view instanceof AdapterView)) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}
否則我要做的就是添加onClickListeners到具有PNG背景的按鈕。我想了解如何以編程方式指定按鈕背景,但我需要讓選擇器功能像聚焦,按下,非聚焦但按下等,以使按鈕背景根據用戶交互而改變。我已閱讀關於此的文檔,但似乎壓倒性的,這就是爲什麼我想我會從這裏開始管理堆的基本知識,並努力工作,直到在代碼中指定選擇器。這可能沒有道理,但應用程序可以分配內存分配的「健康」數量,而不會接近內存不足異常嗎?例如,如果一個應用程序分配了6MB,應該沒問題,但是8MB會推動它,在內存分配方面是否有這樣的限制?再次感謝亞歷克斯洛克伍德您的迴應我將閱讀並重新閱讀它,直到這個東西對我有意義
+1,非常豐富的答案! –
非常感謝!我從中學到了很多東西。我在問題的底部添加了一些信息 –
重新解析評論「20 kb,每個聽起來都很好」 - AFAIK,*文件大小*無關緊要(對於壓縮更好的圖像,這將更小),它關乎*尺寸*是什麼;在內存中,對於全綵色,每像素需要4B,對吧?因此,根據當前設備的實際所需大小加載它時調整圖像的大小非常重要[android docs - 將縮小的版本加載到內存中]。 – ToolmakerSteve