版权声明:本文为博主原创文章,未经博主允许不得转载。
目录(?)[+]
安卓的启动模式 估计都学过 但好长时间内不知道怎么用,感觉都忘了启动模式的存在了,一般都是默认的模式, 然后通过Intent跳转 的时候呢 执行以下finish();感觉挺好用,但是也不能完全符合我们的需求。
standard:每次启动activity都会创建一个activity实例,不管它是否存在
singleTop:当启动activity的时候,如果该activity不在栈顶,会创建一个activity实例,如果他在栈顶存在,执行他的onNewIntent()
singleTask:第一次启动创建实例,以后再启动执行他的onNewIntent()操作,并销毁栈中在他上面的其他实例
singleInstance():第一次启动创建实例,在启动执行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) {
}
onNewIntent()什么时候执行?(对了,他可不是生命周期,他就为了长得跟生命周期很像,容易混个脸熟而已)
onNewIntent()执行了,activity的生命周期是怎样的呢?
还有一种情况就是 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次的跳转动画 ,也是醉了
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而且只管一次
单独用的话我就没 实现过他说的功能 感觉比较坑,一起用最稳。
注意:如果你每次都在oncreate()加载数据 (有变化的都算)那就没法用啦, 或者加载数据的地方在oncreate()和onNewIntent()全写一遍。因为你在后台的话很可能被杀死啦,那你预计让他走onNewIntent() 可能他就走了onCreate()了。
就这些吧 , 没有图 叙述比较多 ,看完了比较辛苦,希望能更加深刻的理解 这些个启动模式在什么时候用,水平有限欢迎指责,有更好的应用场景欢迎 评论
(http://blog.csdn.net/wanghao200906/article/details/49766309)