android的启动模式 到底在什么时候用呢?

目录(?)[+]

  1. 涉及的内容
  2. 一句话理解四种启动模式网上太多了
    1. onNewIntent是什么
  3. 四种启动模式什么时候用呢把网上找的基本都测了一遍自己的感悟吧
    1. 一些常用的flag组合没写的是我很少用没有发言权呀

安卓的启动模式 估计都学过 但好长时间内不知道怎么用,感觉都忘了启动模式的存在了,一般都是默认的模式, 然后通过Intent跳转 的时候呢 执行以下finish();感觉挺好用,但是也不能完全符合我们的需求。

涉及的内容

  • 四种启动模式是什么,在哪里用
  • onNewIntent() 是什么

一句话理解四种启动模式(网上太多了)

  • standard:每次启动activity都会创建一个activity实例,不管它是否存在

  • singleTop:当启动activity的时候,如果该activity不在栈顶,会创建一个activity实例,如果他在栈顶存在,执行他的onNewIntent()

  • singleTask:第一次启动创建实例,以后再启动执行他的onNewIntent()操作,并销毁栈中在他上面的其他实例

  • singleInstance():第一次启动创建实例,在启动执行onNewIntent(),并且单独在一个栈中。

发现重复最多的就是onNewIntent()了。

onNewIntent()是什么

他是什么我说的也不算看代码

    /**
     * This is called for activities that set launchMode to "singleTop" in
     * their package, or if a client used the {@link Intent#FLAG_ACTIVITY_SINGLE_TOP}
     * flag when calling {@link #startActivity}.  In either case, when the
     * activity is re-launched while at the top of the activity stack instead
     * of a new instance of the activity being started, onNewIntent() will be
     * called on the existing instance with the Intent that was used to
     * re-launch it.
     *
     * 

An activity will always be paused before receiving a new intent, so * you can count on {@link #onResume} being called after this method. * *

Note that {@link #getIntent} still returns the original Intent. You * can use {@link #setIntent} to update it to this new Intent. * * @param intent The new intent that was started for the activity. * * @see #getIntent * @see #setIntent * @see #onResume */ protected void onNewIntent(Intent intent) { }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

onNewIntent()什么时候执行?(对了,他可不是生命周期,他就为了长得跟生命周期很像,容易混个脸熟而已)

  • 你得执行intent跳转的时候。(比如什么后台重新启动,在他栈顶的xxActivity 被finish() 然后显示他的,都没执行intent跳转,返回键回退栈。都不会走onNewIntent())
  • 启动模式是singletop(当前activity在栈顶,), singletask(不管在栈的哪里),启动后再次启动

onNewIntent()执行了,activity的生命周期是怎样的呢?

  • 只要执行onNewIntent(),必须就执行intent操作,那肯定当前activiy的onPause()先执行,所以 当前的activity 如果想跳转到自己 并且是singletop的时候执行顺序
    onCreate()
    onStart()
    onResume()
    点击跳转到自己
    onPause()
    onNewIntent()
    onResume()(这里并没有onStop)
  • 还有一种情况就是 app1 和app2 是两个 软件,也就是连个进程,他们分别都有一个activiy。

    当他们的启动模式是standard或者是singletop的时候 现在执行的顺序是:
    开启app2 ,按下home键,开启app1,点击按钮跳转app2
    生命周期是:
    app2 onCreate(开启app2)
    app2 onStart
    app2 onResume
    app2 onPause(按下home键)
    app2 onStop
    app1 onCreate(开启app1)
    app1 onStart
    app1 onResume
    app1 onPause(app1 跳转到app2)
    app2 onCreate
    app2 onStart
    app2 onResume
    app1 onStop

可以看到app2的activity虽然已经在后台了但是依然创建了,下面看一下结构
在cmd里面打 adb shell dumpsys activity 这句话

Running activities (most recent first):
TaskRecord{537b7d08 #44 A com.app1 U 0}
Run #4: ActivityRecord{53651f18 com.app2/.MainActivity}
Run #2: ActivityRecord{5376a210 com.app1/.FirstActivity}
TaskRecord{536c9a5c #2 A com.android.launcher U 0}
Run #1: ActivityRecord{536c8bec com.android.launcher/com.android.launcher2.Launcher}
TaskRecord{53782c88 #42 A com.app2 U 0}
Run #0: ActivityRecord{53768f08 com.app2/.MainActivity}

有三个线程,ui线程,app1 和app2,发现 在#44进程里面出现了 app2的身影。

同样的条件只把 启动模式改为 singleTask或者是singleInstance的话
app2 onCreate
app2 onStart
app2 onResume
app2 onPause(按下home按键)
app2 onStop
app1 onCreate(开启app1)
app1 onStart
app1 onResume
app1 onPause(app1 跳转到app2)
app2 onNewIntent
app2 onRestart
app2 onStart
app2 onResume
app1 onStop

可以发现app2的onNewIntent()执行了。那么看下结构

Running activities (most recent first):
TaskRecord{536b469c #48 A com.app2 U 0}
Run #3: ActivityRecord{5364a00c com.app2/.MainActivity}
TaskRecord{536d82a4 #49 A com.app1 U 0}
Run #2: ActivityRecord{53696ad4 com.app1/.SecondActivity}
Run #1: ActivityRecord{536d6234 com.app1/.FirstActivity}
TaskRecord{536c9a5c #2 A com.android.launcher U 0}
Run #0: ActivityRecord{536c8bec com.android.launcher/com.android.launcher2.Launcher}

可以看到app2的activity并没有出现在app1的栈里面。

所以啊:区别就来了 standard和singletop处于一个集团,他们在一个app跳刀另一个app的时候都会创建新的activity实例, 并且他们都在一个堆栈中,singleTask和singleInstance处于一个集团,他们在app跳刀app的时候都不会产生新的实例,在这种情况下也不会和其他app在一个栈中。(有什么用呢,在用启动模式的时候能理解更加深刻别误以为 onNewIntent肯定会实现,哥就进坑了)

四种启动模式什么时候用呢?(把网上找的基本都测了一遍+自己的感悟吧)

我觉得吧,作为一个程序员在写代码的时候就要先高屋建瓴的感知一下你要写的项目是怎样的,需求是怎样的,提前想好了用什么启动模式,这样才避免启动模式改来改去。

  • standard:这个基本不用说啦,其实大多数的时候都用它,我以前都是用intent各种跳转,跳转的时候把activity给finish()了,然后回退栈的时候在进行跳转 在finish() 这个好累呀。但作为菜鸟的我这样了很久。

  • singleTop:
    1.适合接收通知启动的内容显示页面。
    比如新闻客户端收到了100个推送,你每次点一下推送他都会走一遍某个activiy(显示新闻只用一个activity,只是内容不同而已)的oncreate,onstart,代价就是创建了那么多的activity(不要以为只有推送,比如qq消息提醒)
    a,耗内存
    b, 走了100次的跳转动画 ,也是醉了

    • 但是要注意啊,从其他app跳转到singletop的app的时候是不会走onNewIntent的 上面提到了,所以遇到app相互调用的时候很少用singletop。

    2.某些业务需求是自己的activity跳转到自己的。
    比如 歌曲搜索 你又不会用actionbar,toolbar,那就在activity上面弄个假的呗,搜索完了自己跳转自己现实搜索结果,那就直接用该模式,变化都在onNewIntent()里面对空间进行 赋值之类的。而且也没有跳转动画,人们以为这个activity没有动了,多high。

Intent.FLAG_ACTIVITY_SINGLE_TOP 至于这个问题 它的作用等于singletop,他就管一次,除了activity自己跳转自己,还没想过哪里用,因为两个进程之间跳转 是不走onNewIntent()的。

  • singleTask:(我记得第一次面试问的就是开100个activity如何快速关闭)
    1,适合程序开始的activity(频繁使用的主架构)
    可以用于主架构的activity,(什么新闻啊,侧滑啊)里面有好多fragment,他一般不会被销毁,他可以跳转其他的activity 再回主架构 其他的就销毁呗

        浏览器的主界面。不管从多少个应用启动浏览器,只会启动主界面一次,其余情况都会走onNewIntent,并且会清空主界面上面的其他页面。(忘了从哪看得了)
    
        比如登陆页面也是 入口 那就没太大必要,因为不经常用啊。finish()算了
    

那么问题来了 如果你担心主架构用singleTask以后是否会有问题,那又想一下子删除好多activity,那就这样两个一起来
Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK
清除其他的activity而且只管一次
单独用的话我就没 实现过他说的功能 感觉比较坑,一起用最稳。

  • singleInstance :他只做一件事情
    他的任务栈好复杂呀,我的理解 他只做一件事情就够了
    比如 闹钟里面 负责响的页面,打电话 接通的时候,地图显示的时候,他们都有一个特点 就是你做完这件事了都会返回到上一界面 而没有下一界面。
    最好不要把 singleInstance 放到 中间的activity里面
    a->b->c 如果 b是该启动模式, 那么 a ,c在一个栈里面 b 在一个栈里面,那你如果回退的话就悲剧啦,用户也会感觉奇怪。所以我理解 最好不要 让singleInstance 跳转到其他activity,当然也不绝对。

注意:如果你每次都在oncreate()加载数据 (有变化的都算)那就没法用啦, 或者加载数据的地方在oncreate()和onNewIntent()全写一遍。因为你在后台的话很可能被杀死啦,那你预计让他走onNewIntent() 可能他就走了onCreate()了。

一些常用的flag组合(没写的是我很少用,没有发言权呀)

  • Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK
    这个activity新启动一个栈,原来栈被清空,栈中的activity也被销毁。
  • Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP
    a->b ->a 其中b是以此方法跳转的,b销毁,a走onNewIntent()方法。 比较常用
    b只用 Intent.FLAG_ACTIVITY_CLEAR_TOP: a b都销毁 重建a

就这些吧 , 没有图 叙述比较多 ,看完了比较辛苦,希望能更加深刻的理解 这些个启动模式在什么时候用,水平有限欢迎指责,有更好的应用场景欢迎 评论

(http://blog.csdn.net/wanghao200906/article/details/49766309)

你可能感兴趣的:(Android)