zoukankan      html  css  js  c++  java
  • [Android]知识总结一:Activity

      1.1 首先是Activity的生命周期

    • onCreate, onStart, onRestart, onResume, onPause, onStop, onDestory 这7个回调可以说明Activity的生命周期模型。

      直接上google给的生命周期图来说明:

      

     总结以下的几点:

    1. Activity从创建至用户可见并能够交互,onCreate->onStart->onResume; 其中Created和Started状态属于瞬时状态,只有Resumed状态属于长时间状态。
    2. Activity被遮挡,无论是部分遮挡还是完全不可见,必会调用onPause, 而进入后台的activity有可能因为内存不足等原因被系统杀掉回收,所以如果有需要进行数据保留的情形,请一定在onPause或者onSaveInstance中进行。onStop只有在完全被遮挡时才会被回调。
    3. 当ActivityA启动ActivityB时,其时序图如下:

      

      

      从图中可以看出,当ActivityA处于Resumed状态时,发送了startActivity的消息给ActivityB, 我们可以看出时序为:

      ActivityA: onCreate->onStart->onResume->onPause                                                          ->onStop

      ActivityB:                                                                ->onCreate->onStart->onResume

      d. 启动Activity是通过intent来传递消息的,intent中不光是可以携带参数,也可以设置不同的启动方式,如:

                  setAction(intent, action);

                 setClass(context, class);

                 setComponent(componentName);

                 setClassName(package, classname);

    1.2   Activity和Task Record的关系

    简单的总结一下:

    1. 首先Task Record是用来记录Activity的调用栈情况;栈是一种通用数据结构,先进后出;
    2. 一般而言,一个应用程序如果不特殊指明其对应task, 那么所有的activity的task即是以应用的packagename命名的task。
    3. 可以通过标签android:taskAffinity来指定activity所属的task;
    4. Activity具有4种android:launchMode选项,分别为”standard”, “singleTop”, “singleTask”, “singleInstance”, 其中standard和singleInstance最容易理解,

        Standard:当Activity在被启动时,无论什么情况都会产生一个新的实例加入到栈中记录。

        singleInstance: 表明该Activity在任何时候只有一个实例,并且该实例是单独存在一个栈中记录的,也就是说此栈只存在这一个activity的实例。

        singleTop: 若该Activity已经在栈顶位置时,启动该Activity时,是不会产生实例,而是会触发既有的activity的onNewIntent回调。若该Activity不在栈顶,在行为和standard一致。

        singleTask: 拥有此标签的Activity,也只能产生一个实例,所以当栈中已经存在该实例的话,那么再次启动此Activity时,会将已有栈中的该Activity的实例之上的所有Activity都进行出战操作,并且触发onNewIntent回调。

         5.查看task情况,可以使用以下的命令:

                    adb shell dumpsys activity

      补充几个和Activity相关的知识点:

    用非Activity的context启动Activity,比如说是ApplicationContext, 亦会是service, 启动Activity时,会报错:
    Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
    产生该错误是因为调用startActivity时,默认会将该Activity加入启动该Activity的任务栈,所以当使用applicationContext或是service启动时,会找不到对应的任务栈,只有加入FLAG_ACTIVITY_NEW_TASK标志后,才能正常的启动;
    intent.addFlags(Intent.FLAGS_ACTIVITY_NEW_TASK);

    没有UI的Activity
    有些时候因为需求,我们需要创建一个没有UI界面的Activity,比如说为了使用权限机制时,为了将权限机制模块独立成模块,我们最好的方案是启动一个没有UI的Activity, 在这个Activity中来进行权限控制逻辑,在这里不是来讲述权限控制逻辑,而是说一下没有UI的Activity该怎么来创建;
    一般来说,没有UI的Activity, 是不需要调用setContentView方法的,并且在onStart的回调中,最好setVisible(false),将其设置为不可见;

    数据保存
    第三种,就是关于Activity重建,我们熟悉的在屏幕翻转,语言切换等情况下,Activity会重新创建,也就是说当前的Activity会调用onPause, onStop, onDestory, 并且会重新创建该Activity实例,重新onCreate, onStart, onResume;那我们有的时候,比如说在编辑框中输入姓名“小李”, 在翻转后不用做任何额外的操作,依然存在;但是我们要是做一些状态的记录,比如说一个Button被点击后,我们在内存里记录了其状态,将变量haveClicked置为true后,当翻转后,该变量会被重新置为false,此时该如何处理,Android系统针对此种情况其实早已经留好了回调;
    onSaveInstanceState
    该方法在翻转时,在Activity销毁之前会被调用,位于onStop和onDestory之间,参数为Bundle,开发者可以在此时向Bundle保存一些中间的状态变量;
    onRestoreInstanceState
    该方法不是每次都会被调用,只有在触发一些类似翻转,或是内存不够,将后台的Activity杀死等情形时,当该Activity重新创建时,会被调用;参数也是Bundle, 此Bundle实例中保存的数据就是在
    onSaveInstanceState中进行保存的数据;
    说到这里,我们会发现onCreate的方法参数也是一个命名为savedInstanceState的Bundle类型参数,我们是否会觉得很奇怪,相信在经过这么多年的Android开发,基本上大家都知道这个Bundle实例和onRestoreInstanceState方法里的Bundle参数实例是同一个,区别在于,onCreate的参数在大部分的时候为null, 只有在类似翻转,或是因内存被杀重新创建这些场景下,这个Bundle参数才不会为null,而在onRestoreInstanceState方法中,参数Bundle一定不会为null;

      

        因个人知识和能力所限,如有错误请留言,欢迎讨论,共同进步。

  • 相关阅读:
    s2-032批量脚本
    javascript 1
    threading模块和queue模块实现程序并发功能和消息队列
    Python标准库06 子进程 (subprocess包)
    常用服务对应的正则
    re
    requests
    198. 打家劫舍
    746. 使用最小花费爬楼梯
    70. 爬楼梯
  • 原文地址:https://www.cnblogs.com/yw-technology/p/5373317.html
Copyright © 2011-2022 走看看