美文网首页Android开发
Activity_生命周期和启动模式以及Flags

Activity_生命周期和启动模式以及Flags

作者: 难得糊涂与君勉 | 来源:发表于2017-10-17 11:13 被阅读31次

    从ActivityA跳转到ActivityB过程

    备注:没有单独设定LaunchMode,Activity都是默认的启动模式。onCreate(A)表示第一个Activity中onCreate方法。

    onCreate(A)->onStart(A)->onResume(A)->用户点击跳转动作发生,使用startActivity->onPause(A)
    ->onCreate(B)->onStart(B)->onResume(B)-onStop(A)
    

    1
    在B中onCreate中执行一次Handler,模仿联网的那个延迟,并不会影响后面onStart的执行。
    2
    位于栈顶的Activity先onPause之后,下一个activity才能开始“行动”。
    3
    onPause 和onStop 认为是一对,onStop方法表示的是暂停Activity。onDestroy方法只有在Activity出栈或者被系统回收了才走。
    4
    如果B这个Activity使用了透明的主题,那么当前Activity就不会调用onStop方法。
    5
    onPause方法中不能太耗时,可以做一些存贮数据以及停止动画等工作,onStop中同样也只能做一些轻量级的回收工作。

    资源相关的系统配置发生改变导致Activity被杀死并重新创建

    备注:这里以横竖屏转换为例子,横竖屏就是系统配置发生了改变。另外异常情况下,Activity的
    launchMode不在有效果。

    onCreate->onStart()->onResume->这时候旋转屏幕->onPause->onSaveInstanceState->onStop->onDestroy
    ->onCreate->onStart->onRestoreInstanceState->onResume
    

    1
    系统会自动调用onSaveInstanceState来保存当前Activity的状态,这个调用是在onStop之前,但是和onPause方法谁先调用
    不确定,这个方法只有在Activity被异常终止情况下才会回调并把里面保存的bundle作为参数传递给onRestoreInstanceState
    方法。
    2
    由于是系统配置发生的改变,所以Activity最后完全销毁了。
    3
    系统默认保存当前Activity视图结构,比如:文本框输入数据,listView的滚动位置等等之类的。
    其实现的原理是:Activity被异常终止,调用onSaveInstanceSave方法,这个方法委托window保存数据,然后window委托
    顶层容器保存数据,再往下委托下一层容器保存数据,可以说,是通过委托办法,所以说一个你想保存什么数据,可以通说View直接查看方法。
    4
    onRestoreInstanceState 与onCreate中都有Bundle类型参数,这两个有什么不同呢:
    后者Bundle中不一定有值,在使用前需要判断是否为null,但是在onRestoreInstanceState方法中,表示肯定
    有值。

    系统配置改变之后,不想重建Activity,需借助android:configChanges属性

    configChanges属性一览表

    表示的意思是,如果出现了上述描述的情况,如果在代码中没有通过configChanges指定的话,那么Activity就会
    重新销毁重建。
    1
    解决横竖屏问题
    添加:android:configChanges=“orientation|screenSize”
    那么屏幕旋转之后就不会在销毁Activity并且重建Activity了,并且系统还提供了一个回调方法:

    
        @Override
        public void onConfigurationChanged(Configuration newConfig) {
            super.onConfigurationChanged(newConfig);
            //Activity不会销毁重建
            if(newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE){
                //Configuration.ORIENTATION_LANDSCAPE表示的是横向
                //Configuration.ORIENTATION_PORTRAIT表示的是竖向
    
            }else {
                
            }
                
        }
    

    另外还可以通过:android:screenOrientation = landscape或者portrait
    这两个方法都可行,但是前面的方法,Activity不会重建了,但是依旧横屏展示了,如果是后者,那么直接不予许手机转屏了。

    Activity的启动模式_singleTop

    栈顶复用模式,如果新Activity已经位于任务栈的栈顶,那么此Activity就不会被创建,同时会回调onNewIntent方法。
    1
    当前栈内没有B的 生命周期:

    onCreate(A)->onStart(A)->onResume(A)->用户点击跳转动作->onPause(A)->onCreate(B)
    ->onStart(B)->onResume(B)->onStop(A)
    

    2
    当前栈内有B存在时候,由B启动B:

    (1)startActivtiy
    onPause(B)->onNewIntent(B)->onResume(B)->此时按照回退键->onPause(B)->onRestart(A)->onStart(A)
    ->onResume(A)->onStop(B)->onDestroy(B)
    (2)startActivityForResult
    onPause(B)->onCreate(B)->onStart(B)->onResume(B)->onStop(B)
    此时栈内为ABB了
    

    3
    经过测试发现,没有界面跳转的动画,但是界面可以刷新。

    Activity的启动模式_singleTsk

    栈内复用模式,一种单实例模式。这种模式需要考虑“栈”的概念
    1
    栈,可以翻译为:任务相关性,这个参数标识了一个Activity所需要的任务栈的名字。
    默认情况下,所有Activity所需的任务栈的名字为应用的包名。
    但是我们也可以为每个Activity单独指定TaskAffinity属性,而且不能和包名一致。一般就是用于singleTask
    或者allowTaskReparenting 属性配对使用。
    另外,栈可以分为前台任务栈和后台任务栈。后台任务栈中的activity处于暂停状态。
    (1)
    android:TaskAffinity和singleTask配合使用,待启动的Activity会运行在名字和TaskAffinity相同的任务栈中
    (2)
    TaskAffinity和allowTaskReparenting结合时候,当一个应用A启动了应用B的某个Activity,如果这个Activity中
    allowTaskReparenting属性为true,那么,回到桌面,你再点击B的图标,进去之后展示的是B的这个Activity,
    而不是MainActivity了。
    2
    singleTask情况描述一:
    如果当前任务栈s1中有ABC,D以任务栈s2启动,那么系统就会创建任务栈s2,并把创建的D放入。
    singleTask情况描述二:
    如果当前任务栈s1中有ABC,D以任务栈s1启动,那么系统会创建新的D放入。
    singleTask情况描述三:
    如果当前任务栈s1中有DABC,D以任务栈s1启动,那么系统会把D切换到栈顶,并调用onNewIntent
    同时它有clearTop作用,会把ABC弹出栈。

    (1)默认的任务栈,栈内没有B,点击跳转
      周期和正常启动一样,因为栈里没有这个Activity的原因。
    (2)默认的任务栈,栈内有B,采用startActivity
    onPause(C)->onNewIntent(B)->onRestart(B)->onStart(B)->onResume(B)->onStop(C)->onDestroy(C)
    (3)默认的任务栈,栈内有B,采用startActivityForResult
    onPause(C)->onActivityResult(C)->onReusme(C)->onPause(C)->onNewIntent(B)->onRestart(B)
    ->onStart(B)->onResume(B)-onStop(C)->onDestroy(C)
    

    Activity的启动模式_singleInstance

    这个模式是singleTask模式的加强版,拥有singleTask的所有特性,另外,这种模式的Activity,只能单独位于
    一个任务栈中。

    (1)A跳转到B中,暂时没有B
    正常的声明周期,存在幅度较大的跳转
    (2)ABC,现在从C跳转到B,startActivity
    onPause(C)->onNewIntent(B)->onRestart(B)->onStart(B)->onResume(B)->onStop(C)
    ->并不会销毁C,只是从一个栈跳到了另一个栈->此时按回退键->onPause(B)->onRestart(C)
    ->onStart(C)->onResume(C)->onStop(B)->onDestroy(B)->因为B弹出栈了。
    (3)ABC,现在从C跳转到B,startActivityForResult
    onPause(C)->onActivityResult(C)->onResume(C)->onPause(C)->onNewIntent(B)
    ->onRestart(B)->onStart(B)->onResume(B)->onStop(C)->此时按回退键->onPause(B)
    ->onRestart(C)->onStart(C)->onReusme(C)->onStop(B)->onDestroy(B)
    此时任务栈s1中只有AC,另外B和B所在的任务栈都没了
    

    上述测试基于Android4.4系统

    Activity中用到的Flag

    Activity的Flags有很多,它们被称为标志位,它们的作用很多,可以设定Activity的启动模式,可以影响Activity的运行状态。
    1
    FLAG_ACTIVITY_NEW_TASK
    给Activity指定singleTask的启动模式,效果和在XML中指定一样,但是,如果同时在清单文件中指定和代码中
    通过此标志位指定,那么标志位的优先级最高,以它为准。
    2
    FLAG_ACTIVITY_SINGLE_TOP
    通过此标志位,给Activity指定singleTop的启动模式。
    3
    FLAG_ACTIVITY_CLEAR_TOP
    通过此标志位的Activity,当它启动时,在同一个任务栈中所有位于他上面的Activity都要出栈。这个标志位一般和singleTask模式一起用。如果被启动的Activity是standard模式启动,那么它连同它之上的activity都会出栈,系统会
    创建新的实例放进去。
    4
    FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
    recents :多任务键,可以看到用户最近使用的应用,这个经过测试,给根Activity使用的时候,用户点击最近任务键,看不见这个应用。

    相关文章

      网友评论

        本文标题:Activity_生命周期和启动模式以及Flags

        本文链接:https://www.haomeiwen.com/subject/pzgkuxtx.html