2017-08-25 52 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()之前。