launchMode解析

launchMode解析


什么是任务栈

管理Activity进出顺序的栈,也叫回退任务栈(back task stack),当按下手机模拟键“返回”时将会依次弹出任务栈栈顶的Activity,直到该任务栈中所有的栈都退出,将会返回到主页。

TaskAffinity属性

定义该Activity所属任务栈,未填写该属性则默认加入到在当前包名的任务栈中。

SingleTask

1.singleTask:一个任务栈中只实现一个Activity实例,当已经有该Activity时清除在其上的所有Activity,并调用onNewIntent()方法

当用taskAffinity属性定义该Activity为其他包名时,将会在其他任务栈中创建该Activity,在该Activity中启动的Activity也将加入这个新建的Activity所属的任务栈,当其属于其他任务栈时回退栈就已经改变了。

这里有4种情况:
1.同一个应用中调用并加taskAffinity属性
2.同一个应用中调用不加taskAffinity属性
3.不同一个应用中调用并加taskAffinity属性
4.不同一个应用中调用不加taskAffinity属性

1.同一个应用中调用并加taskAffinity属性
在SecondActivity中修改launchMode和taskAffinity:
launchMode解析_第1张图片
加入之后依次打开MainActivity->SecondActivity->ThirdActivity,其任务栈就有了两个:

TASK zzz.zz id=55
  ACTIVITY com.lhq.launchmodedemo/.ThirdActivity 52752cb4 pid=17295
    Local FragmentActivity 5273348c State:
      mCreated=truemResumed=true mStopped=false mReallyStopped=false
      mLoadersStarted=true
    FragmentManager misc state:
      mHost=android.support.v4.app.FragmentActivity$HostCallbacks@52733568
      mContainer=android.support.v4.app.FragmentActivity$HostCallbacks@52733568
      mCurState=5 mStateSaved=false mDestroyed=false
    View Hierarchy:
      ...

  ACTIVITY com.lhq.launchmodedemo/.SecondActivity 52719c98 pid=17295
    Local FragmentActivity 52716590 State:
      mCreated=truemResumed=false mStopped=true mReallyStopped=true
      mLoadersStarted=true
    FragmentManager misc state:
      mHost=android.support.v4.app.FragmentActivity$HostCallbacks@5272d924
      mContainer=android.support.v4.app.FragmentActivity$HostCallbacks@5272d924
      mCurState=2 mStateSaved=true mDestroyed=false
    View Hierarchy:
     ...

TASK com.lhq.launchmodedemo id=54
  ACTIVITY com.lhq.launchmodedemo/.MainActivity 52756cc0 pid=17295
    Local FragmentActivity 52717c84 State:
      mCreated=truemResumed=false mStopped=true mReallyStopped=true
      mLoadersStarted=true
   ...

可以看到有两个任务栈:zzz.zz和未定义taskAffinity而默认使用包名的任务栈com.lhq.launchmodedemo,在模拟器上的任务管理器中显示如下:
launchMode解析_第2张图片
回退顺序:
zzz.zz栈:ThirdActivity->SecondActivity
com.lhq.launchmodedemo栈:MainActivity

2.同一个应用中调用不加taskAffinity属性

  • 只有一个任务栈TASK com.lhq.launchmodedemo id=14
TASK com.lhq.launchmodedemo id=14
  ACTIVITY com.lhq.launchmodedemo/.ThirdActivity 52866e08 pid=6814
    Local FragmentActivity 52764cd8 State:
      mCreated=truemResumed=true mStopped=false mReallyStopped=false
      mLoadersStarted=true
    FragmentManager misc state:
      mHost=android.support.v4.app.FragmentActivity$HostCallbacks@52764e20
      mContainer=android.support.v4.app.FragmentActivity$HostCallbacks@52764e20
      mCurState=5 mStateSaved=false mDestroyed=false
    View Hierarchy:
      ...

  ACTIVITY com.lhq.launchmodedemo/.SecondActivity 5282210c pid=6814
    Local FragmentActivity 52731a78 State:
      mCreated=truemResumed=false mStopped=true mReallyStopped=true
      mLoadersStarted=true
    FragmentManager misc state:
      mHost=android.support.v4.app.FragmentActivity$HostCallbacks@52731b28
      mContainer=android.support.v4.app.FragmentActivity$HostCallbacks@52731b28
      mCurState=2 mStateSaved=true mDestroyed=false
    View Hierarchy:
      ...

  ACTIVITY com.lhq.launchmodedemo/.MainActivity 5285612c pid=6814
    Local FragmentActivity 52729080 State:
      mCreated=truemResumed=false mStopped=true mReallyStopped=true
      mLoadersStarted=true
    FragmentManager misc state:
      mHost=android.support.v4.app.FragmentActivity$HostCallbacks@52729b50
      mContainer=android.support.v4.app.FragmentActivity$HostCallbacks@52729b50
      mCurState=2 mStateSaved=true mDestroyed=false
    View Hierarchy:
      ...
  • 任务管理器:
    launchMode解析_第3张图片

  • 回退栈:ThirdActivity->SecondActivity->MainActivity

3.不同一个应用中调用并加taskAffinity属性

  • 两个任务栈
TASK null id=26
  ACTIVITY com.lhq.launchmodedemo/.ThirdActivity 52843f6c pid=29809
    Local FragmentActivity 5275e538 State:
      mCreated=truemResumed=true mStopped=false mReallyStopped=false
      mLoadersStarted=true
    FragmentManager misc state:
      mHost=android.support.v4.app.FragmentActivity$HostCallbacks@5275e680
      mContainer=android.support.v4.app.FragmentActivity$HostCallbacks@5275e680
      mCurState=5 mStateSaved=false mDestroyed=false
    View Hierarchy:
      ...

  ACTIVITY com.lhq.launchmodedemo/.SecondActivity 52823538 pid=29809
    Local FragmentActivity 52744200 State:
      mCreated=truemResumed=false mStopped=true mReallyStopped=true
      mLoadersStarted=true
    FragmentManager misc state:
      mHost=android.support.v4.app.FragmentActivity$HostCallbacks@52744348
      mContainer=android.support.v4.app.FragmentActivity$HostCallbacks@52744348
      mCurState=2 mStateSaved=true mDestroyed=false
    View Hierarchy:
      ...

TASK com.lhq.launchmodedemo id=25
  ACTIVITY com.lhq.launchmodedemo/.MainActivity 5282210c pid=29809
    Local FragmentActivity 5272cfe8 State:
      mCreated=truemResumed=false mStopped=true mReallyStopped=true
      mLoadersStarted=true
    FragmentManager misc state:
      mHost=android.support.v4.app.FragmentActivity$HostCallbacks@5272dab8
      mContainer=android.support.v4.app.FragmentActivity$HostCallbacks@5272dab8
      mCurState=2 mStateSaved=true mDestroyed=false
    View Hierarchy:
      ...
  • 任务管理器:在未用图库应用调用起本应用时,就已经有两个任务栈了。当用图库调起SecondActivity时,不会再重新新建任务栈,而是把SecondActivity移动到栈顶。
  • 回退任务栈:SecondActivity->桌面

4.不同一个应用中调用不加taskAffinity属性(通过图库调起,后面的不同引用调用也是指图库)

  • 一个任务栈
TASK com.lhq.launchmodedemo id=290
  ACTIVITY com.lhq.launchmodedemo/.SecondActivity 101b9a9 pid=23559
    Local FragmentActivity e934f4d State:
      mCreated=truemResumed=true mStopped=false mReallyStopped=false
      mLoadersStarted=true
    FragmentManager misc state:
      mHost=android.support.v4.app.FragmentActivity$HostCallbacks@d6e782d
      mContainer=android.support.v4.app.FragmentActivity$HostCallbacks@d6e782d
      mCurState=5 mStateSaved=false mDestroyed=false
    View Hierarchy:
      ...

  ACTIVITY com.lhq.launchmodedemo/.MainActivity aea3932 pid=23559
    Local FragmentActivity ecd2145 State:
      mCreated=truemResumed=false mStopped=true mReallyStopped=true
      mLoadersStarted=true
    FragmentManager misc state:
      mHost=android.support.v4.app.FragmentActivity$HostCallbacks@3a6e0e0
      mContainer=android.support.v4.app.FragmentActivity$HostCallbacks@3a6e0e0
      mCurState=2 mStateSaved=true mDestroyed=false
    View Hierarchy:
      ...
  • 任务管理器:没有新建任务栈
  • 回退栈:在原应用中回退:SecondActivity->MainActivity

singleTask总结

2.当其他应用调用到该singleTask的Activity时:
  1.当该Activity已启动,并在后台通过其他应用启动不会再构建任务栈,而是在原任务栈的基础上将该singleTaskActivity上的其他Activity都清除
  2.当该Activity未启动时,将新建任务栈并将该Activity置于栈底

只需要注意,当加上了taskAffinity属性,且指定了不同的包名,就会将Activity加入到新建任务栈,只需要理解了任务栈是栈的形式存储和弹出Activity就能知道它的回退顺序。

singleInstance

和singleTask类似一个任务栈一个实例,启动另一个任务栈,但是区别是从该Activity启动的其他Activity和它并不属于一个任务栈。
这个launchMode我们分两种情况讨论:有无taskAffinity属性,而在其他应用启动singleInstance Activity的情况就不说了,看完下面的测试就明白了
1.未定义taskAffinity:

TASK com.lhq.launchmodedemo id=87
  ACTIVITY com.lhq.launchmodedemo/.ThirdActivity 529c3dd8 pid=30275
    Local FragmentActivity 5271db68 State:
      mCreated=truemResumed=true mStopped=false mReallyStopped=false
      mLoadersStarted=true
    FragmentManager misc state:
      mHost=android.support.v4.app.FragmentActivity$HostCallbacks@5271dc7c
      mContainer=android.support.v4.app.FragmentActivity$HostCallbacks@5271dc7c
      mCurState=5 mStateSaved=false mDestroyed=false
    View Hierarchy:
      ...

  ACTIVITY com.lhq.launchmodedemo/.MainActivity 527cb71c pid=30275
    Local FragmentActivity 52716150 State:
      mCreated=truemResumed=false mStopped=true mReallyStopped=true
      mLoadersStarted=true
    FragmentManager misc state:
      mHost=android.support.v4.app.FragmentActivity$HostCallbacks@52716cb0
      mContainer=android.support.v4.app.FragmentActivity$HostCallbacks@52716cb0
      mCurState=2 mStateSaved=true mDestroyed=false
    View Hierarchy:
      ...

TASK com.lhq.launchmodedemo id=88
  ACTIVITY com.lhq.launchmodedemo/.SecondActivity 527f5e18 pid=30275
    Local FragmentActivity 52714b34 State:
      mCreated=truemResumed=false mStopped=true mReallyStopped=true
      mLoadersStarted=true
    FragmentManager misc state:
      mHost=android.support.v4.app.FragmentActivity$HostCallbacks@52727970
      mContainer=android.support.v4.app.FragmentActivity$HostCallbacks@52727970
      mCurState=2 mStateSaved=true mDestroyed=false
    View Hierarchy:
    ...
  • 任务管理器中却只有一个任务:
      launchMode解析_第4张图片
      
  • 回退栈:ThirdActivity->MainActivity->SecondActivity->桌面

    这里有个细节:当我依次打开三个Activity,然后将该任务栈置于后台(也就是非可见的状态,比如回到主页)时,再次进入该应用,再次按返回弹出任务栈时,它的弹出顺序变了:ThirdActivity->MainActivity->桌面,这个就很奇怪,但是我查看过任务栈列表,SecondActivity在我回到该应用时还在,但是在回退中再也无法启动到SecondActivity,原因我也没搞清楚,所以这种形式的singleInstance Activity不建议使用。


2.定义taskAffinity:
TASK com.lhq.launchmodedemo id=106
  ACTIVITY com.lhq.launchmodedemo/.ThirdActivity 52750184 pid=11450
    Local FragmentActivity 5273cb94 State:
      mCreated=truemResumed=true mStopped=false mReallyStopped=false
      mLoadersStarted=true
    FragmentManager misc state:
      mHost=android.support.v4.app.FragmentActivity$HostCallbacks@5273cc60
      mContainer=android.support.v4.app.FragmentActivity$HostCallbacks@5273cc60
      mCurState=5 mStateSaved=false mDestroyed=false
    View Hierarchy:
      ...

  ACTIVITY com.lhq.launchmodedemo/.MainActivity 52a6de0c pid=11450
    Local FragmentActivity 52713d68 State:
      mCreated=truemResumed=false mStopped=true mReallyStopped=true
      mLoadersStarted=true
    FragmentManager misc state:
      mHost=android.support.v4.app.FragmentActivity$HostCallbacks@527148c8
      mContainer=android.support.v4.app.FragmentActivity$HostCallbacks@527148c8
      mCurState=2 mStateSaved=true mDestroyed=false
    View Hierarchy:
      ...

TASK zzz.zz id=107
  ACTIVITY com.lhq.launchmodedemo/.SecondActivity 52739af8 pid=11450
    Local FragmentActivity 5274c0ac State:
      mCreated=truemResumed=false mStopped=true mReallyStopped=true
      mLoadersStarted=true
    FragmentManager misc state:
      mHost=android.support.v4.app.FragmentActivity$HostCallbacks@5274c1f4
      mContainer=android.support.v4.app.FragmentActivity$HostCallbacks@5274c1f4
      mCurState=2 mStateSaved=true mDestroyed=false
    View Hierarchy:
      ...
  有两个任务栈zzz.zz和com.lhq.launchmodedemo,同时在SecondActivity中启动的ThirdActivity加入到了com.lhq.launchmodedemo id=106的栈中,zzz.zz id=107任务栈只有SecondActivity一个。   
  • 看模拟器中的任务管理器中显示的任务个数,理论上说应该是2个(确实是两个):
    launchMode解析_第5张图片

  • 回退栈:各栈各自回退,ThirdActivity->MainActivity->桌面
       SecondActivity->桌面

singleTask和singleInstance对比:

同:栈中只能有一个实例,当定义了taskAffinity属性时将会形成新的任务栈,且能显示在任务管理器中
异:在singleTask Activity中启动其他的Activity会加入到该singleTask Activity所在的栈中,而singleInstance Activity所在的栈中只有该Activity,即使在该Activity中启动其他Activity也不会再加入到该栈中,而是加入到其他栈中去。

Activity onNewIntent()的使用

1.除了standard模式之外都有可能调用到该方法,最好的办法就是在onCreate()方法和onNewIntent()方法中调用同一个处理数据的方法。

调用到的顺序:onNewIntent()->onStart()->onResume()

而在Activity中也有一个方法setIntent(intent)将会覆盖原来的intent,然后可以通过getIntent()方法获取最新的intent。可以查看Activity中的源码,最好用setIntent()来设置Intent,然后在其他方法中通过getIntent()获取intent对象。这样能尽可能的解藕。

应用

singleTop:通知内容显示详情的页面,导航页在进入主页时点击过快有时会形成两个主页面,也可以用singleTop,但是用singltTask会比较建议
singleTask:App的主界面
singltInstance:(不建议使用)拨号界面就是singleInstance实例

demo地址:https://github.com/Adam0407/LaunchModeDemo

参考:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0520/2897.html

你可能感兴趣的:(android)