我的申请中有几项活动。首先是启动活动(A),创建(startActivityWithResult)一个对话活动"首先运行向导" (B)从该用户可以启动一些设置活动(C)。当用户从活动C(通过后退按钮)返回而不是返回活动B(或完全销毁它并使用saveInstanceState创建它)时,它首先调用onStart,onResume of original acitivity B然后创建一个新的活动B实例,而不是saveInstanceState。用户只能看到新实例,但旧实例仍然存在,消耗内存并获取onStart和onStop(即使它们被隐藏)。现在我有多个B实例和从活动C返回后创建的新实例。我必须关闭B的所有实例才能返回A. 我的问题是:如何避免创建同一个实例B的多个实例?我尝试在清单中为B设置 singleTop , singleTask 或 singleInstance ,但它确实无效。还有另一种方法可以在我的应用程序中获取活动C,因此我不想更改活动C.目前我在创建活动B或C时没有设置任何标记。
有清单文件:
活动A:
<activity
android:name=".A"
android:label="@string/app_name"
android:launchMode="singleTop"
android:screenOrientation="portrait"
android:stateNotNeeded="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
活动B:
<activity
android:name=".B"
android:launchMode="singleInstance"
android:label="B"
android:parentActivityName=".A"
android:theme="@style/WizardDialog">
</activity>
活动C:
<activity
android:name=".C"
android:label="C">
</activity>
B有WizardDialog主题(活动A在B下部分可见):
<style name="WizardDialog" parent="@style/AppDialogBasic">
<item name="android:maxWidth">300dp</item>
<item name="android:maxHeight">360dp</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowSoftInputMode">stateAlwaysHidden</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
<item name="android:windowActionModeOverlay">true</item>
</style>
还有sysdump活动的输出:
ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)
Display #0 (activities from top to bottom):
Stack #1:
mFullscreen=true
mBounds=null
Task id #88
mFullscreen=true
mBounds=null
mMinWidth=-1
mMinHeight=-1
mLastNonFullscreenBounds=null
TaskRecord{be4d271 #88 A=com.a.a U=0 StackId=1 sz=3}
Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.a.a/.WaitingActivity }
Hist #2: ActivityRecord{fd61815 u0 com.a.a/.SetupWizardActivity t88}
Intent { cmp=com.a.a/.SetupWizardActivity }
ProcessRecord{d21940e 17900:com.a.a/u0a79}
Hist #1: ActivityRecord{f891058 u0 com.a.a/.SetupWizardActivity t88}
Intent { cmp=com.a.a/.SetupWizardActivity }
ProcessRecord{d21940e 17900:com.a.a/u0a79}
Hist #0: ActivityRecord{e2bb06a u0 com.a.a/.WaitingActivity t88}
Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.a.a/.WaitingActivity }
ProcessRecord{d21940e 17900:com.a.a/u0a79}
Running activities (most recent first):
TaskRecord{be4d271 #88 A=com.a.a U=0 StackId=1 sz=3}
Run #2: ActivityRecord{fd61815 u0 com.a.a/.SetupWizardActivity t88}
Run #1: ActivityRecord{f891058 u0 com.a.a/.SetupWizardActivity t88}
Run #0: ActivityRecord{e2bb06a u0 com.a.a/.WaitingActivity t88}
mResumedActivity: ActivityRecord{fd61815 u0 com.a.a/.SetupWizardActivity t88}
Stack #0:
mFullscreen=true
mBounds=null
Task id #75
mFullscreen=true
mBounds=null
mMinWidth=-1
mMinHeight=-1
mLastNonFullscreenBounds=null
TaskRecord{cf23856 #75 I=com.google.android.apps.nexuslauncher/.NexusLauncherActivity U=0 StackId=0 sz=1}
Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000100 cmp=com.google.android.apps.nexuslauncher/.NexusLauncherActivity }
Hist #0: ActivityRecord{de71b57 u0 com.google.android.apps.nexuslauncher/.NexusLauncherActivity t75}
Intent { act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000100 cmp=com.google.android.apps.nexuslauncher/.NexusLauncherActivity }
ProcessRecord{bc76608 2088:com.google.android.apps.nexuslauncher/u0a20}
Running activities (most recent first):
TaskRecord{cf23856 #75 I=com.google.android.apps.nexuslauncher/.NexusLauncherActivity U=0 StackId=0 sz=1}
Run #0: ActivityRecord{de71b57 u0 com.google.android.apps.nexuslauncher/.NexusLauncherActivity t75}
mFocusedActivity: ActivityRecord{fd61815 u0 com.a.a/.SetupWizardActivity t88}
mFocusedStack=ActivityStack{b84edc4 stackId=1, 1 tasks} mLastFocusedStack=ActivityStack{b84edc4 stackId=1, 1 tasks}
mSleepTimeout=false
mCurTaskIdForUser={0=88}
mUserStackInFront={}
mActivityContainers={0=ActivtyContainer{0}A, 1=ActivtyContainer{1}A}
mLockTaskModeState=NONE mLockTaskPackages (userId:packages)=0:[]
mLockTaskModeTasks[]
答案 0 :(得分:0)
因此,在 onStart 期间,在A中创建了额外的活动实例。我完全忽视那个地方。 A的 onStart 被调用,因为B是部分透明的对话框,当C被破坏时A也被带到前面。我用旗帜解决了这个问题:
firstStartWizardIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivityForResult(firstStartWizardIntent /* B */, DIALOG_FIRST_START_WIZARD);
并将B的 launchMode 设置为标准。