2017-08-25 25 views
0

我有一個內存不足的問題。活動的多個實例內存不足

我有一套活動和跨應用程序的類。

我將launchMode設置爲SingleTop,將noHistory設置爲在每個活動的清單中爲true。 我還設置android: largeHeap = "true"

一個主要的和其他五項活動我叫A,B,C,d,E

A,B,C總是顯示在堆中,但d的單個實例和E加大號實例的每位新意圖及其startActivity

C使用相同的對象(列表視圖,散列映射,simpleAdapter)在d也用和E

這種情況發生時:

主引導,再開機C, C cal l D和D調用E並返回C. C總是有一個實例,而D和E通過每次佔用1 MB指示它們的實例,最終導致Oom重疊174Mb可用於我的應用程序。

對於我運行此代碼的所有活動,例如來自activityB,startC,activityC。

Intent activityC = new Intent (getBaseContext, activityC.class); // Try too getApplicationContext, activityC.this but instances remain anyway. 

activityC.setFlags (Intent.FLAG_ACTIVITY_CLEAR_TOP); // I try too SINGLE_TOP, NEW_TASK, CLEAR_TASK same result 

Finish(); // I also tried to call finish() after startActivity() with the same result 
startActivity (activityC); 

這一切都毫無價值。

我還使用了freeMemory()函數調用每個活動的onDestroy()但有無變化無關

Public void freeMemory() { 

System.runFinalization(); 
Runtime.getRuntime(). Gc(); 
System.gc(); 

} 

我已經試圖執行onNewIntent但我從來沒有得到它。

在D和E onDestroy我試圖設置爲空在onCreate()中創建的所有對象(私有),但不成功。

目前我正在嘗試使用華碩和Android 5.02平板電腦。

請勿使用Handler,Timer或AsyncTask。

對於多大的努力我沒有(我真的嘗試了很多)A,B,C總是顯示在堆中的單個實例,而d和E

我還創建了一個演示,儘量集中在問題,但我沒有得到結果。在SINGLE_TOP演示中,您可以按照您的預期工作,並且每個活動的重複次數超過一次。

什麼可以保留新的實例?

清單:

<?xml version="1.0" encoding="utf-8"?> 

<uses-permission android:name="android.permission.INTERNET" /> 

<application 
    android:name=".TEST" 
    android:allowBackup="true" 
    android:hardwareAccelerated="false" 
    android:icon="@drawable/logo" 
    android:label="@string/app_name" 
    android:largeHeap="true" 
    android:supportsRtl="true" 
    android:theme="@style/AppTheme"> 
    <activity 
     android:name=".ActivityA" 
     android:hardwareAccelerated="false" 
     android:label="@string/app_name" 
     android:screenOrientation="portrait"> 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 
      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 
    <activity 
     android:name=".ActivityE" 
     android:enabled="true" 
     android:hardwareAccelerated="false" 
     android:label="@string/app_name" 
     android:launchMode="singleTop" 
     android:noHistory="true" 
     android:screenOrientation="portrait" 
     android:theme="@style/AppTheme" /> 

    <activity 
     android:name=".ActivityD" 
     android:hardwareAccelerated="true" 
     android:label="@string/app_name" 
     android:launchMode="singleTop" 
     android:noHistory="true" 
     android:screenOrientation="portrait" 
     android:theme="@style/AppTheme.NoActionBar" /> 

    <activity 
     android:name=".ActivityC" 
     android:hardwareAccelerated="true" 
     android:label="@string/app_name" 
     android:launchMode="singleTop" 
     android:noHistory="true" 
     android:screenOrientation="portrait" 
     android:theme="@style/AppTheme.NoActionBar" /> 

    <activity 
     android:name=".ActivityB" 
     android:hardwareAccelerated="true" 
     android:launchMode="singleTop" 
     android:noHistory="true" 
     android:screenOrientation="portrait" 
     android:theme="@style/AppTheme.NoActionBar" /> 


    <activity android:name=".TempActivity" 
     android:launchMode="singleTop" 
     android:noHistory="true" 
     /> 
</application> 

</manifest> 

我注意到,當你從一個活動切換到另一個logcat的告訴我: 8月8日至26日:22:33.607 905-5207 /? W/ActivityManager:從完成ActivityRecord調用startActivity {6d2eb11 u0 danielezampieri.TEST /。ActivityC t472 f};強制Intent.FLAG_ACTIVITY_NEW_TASK用於:Intent {flg = 0x24020000 cmp = danielezampieri.TEST/.ActivityD} 因爲?這是什麼意思?是否因爲ActivityC生成多個實例?

但是,我在startactivity之後對finish()方法進行了評論,只有上面提到的活動顯示了多個實例。

更新! 我專注於產生問題的觀點。無論如何,感謝您的建議。 在activityC我具有延伸對話框兩個類(顯示多個實例,並且佔據無用存儲器中的一個),創造了它們的活性的OnCreate與

newmydialog1 = New mydialog1 (this) 
newmydialog1 = New mydialog2 (this) 

然後我打電話

newmydialog1.show 

在mydialog1有運行

newmydialog2.show 

如果我運行mydialog2,除非我按下按鈕,我不創建activityC的多個實例的按鈕在這裏運行mydialog2是相信每個創建的實例的activityC上的內存泄漏。 我試圖調用newmydialog2.cancel/dismiss,然後在mydialog1的cancel()之前將newmydialog2設置爲null,但沒有任何結果。 我還能做什麼?

+0

發佈您的清單請 –

+0

也可能您D和E的事例不會消失的原因是因爲某些東西正在引用它們。要檢查這一點,運行你的應用程序,從C到D到E並回幾次。然後進行堆轉儲,查看堆中有多少個C,D和E實例。還可以執行'adb shell dumpsys activity activity'並查看任務中的活動列表。 –

+0

我建議實施LeakCanary來幫助追蹤你的內存泄漏:https://github.com/square/leakcanary。另外,如果您運行'lint'Gradle任務,是否會在成員/靜態變量中存儲任何關於存儲上下文值的警告?我的猜測是一個Context變量被作爲一個硬引用存儲在某個地方,導致Activity無法收集垃圾。 – Bradford2000

回答

0

。如果C & d &ê分享你爲什麼不使ActivityC相同的對象有你的ç& d &Ë內容之間的ViewFlipper「翻轉」,如果你有很多圖片的嘗試擴展他們失望或者重複使用它們而不是每次都創建它們......並且如果您在翻動視圖時擔心落後,請嘗試使用異步任務來創建活動時創建的D的內容......同樣使用RecyclerViews可能會有所幫助,而不是ListViews .....我希望我幫助你的東西:)

+0

+1重新使用/回收圖像。你可以用LruCache很容易地做到這一點:https://developer.android.com/reference/android/util/LruCache.html – Bradford2000

+0

@haikal不依賴於圖像e不同於應用程序的活動部分。查看我的更新。 – Daniele

0

問題解決方案

mydialog2的新版本必須位於mydialog1類中,並且位於newmydialog2.show()之前。