完成子活动后,避免创建新的活动实例

时间:2017-10-27 14:37:13

标签: android android-activity

我的申请中有几项活动。首先是启动活动(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[]

1 个答案:

答案 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 设置为标准