美文网首页
Android四大应用组件之Activity篇

Android四大应用组件之Activity篇

作者: flynnny | 来源:发表于2021-02-28 23:46 被阅读0次

    总结自Android四大应用组件之Activity篇
    Android四大应用组件之Activity篇https://www.jianshu.com/p/d22981a8ad0e
    Android四大应用组件之Service篇https://www.jianshu.com/p/f7d57803b86e
    Android四大应用组件之ContentProvider篇https://www.jianshu.com/p/5f783f3db22d
    Android四大应用组件之BroadcastReceiver篇https://www.jianshu.com/p/e6283dec21c7

    理论概述

    1.png 2.png 3.png 4.png 5.png 11.png

    Activity生命周期

    6.png

    1.当Activity位于栈顶时,此时正好处于屏幕最前方,此时处于运行状态;
    2.当Activity失去了焦点但仍然对用于可见(如栈顶的Activity是透明的或者栈顶Activity并不是铺满整个手机屏幕),此时处于暂停状态;
    3.当Activity被其他Activity完全遮挡,此时此Activity对用户不可见,此时处于停止状态;
    4.当Activity由于人为或系统原因(如低内存等)被销毁,此时处于销毁状态;

    7.png

    1.Activity实例是由系统自动创建,并在不同的状态期间回调相应的方法。一个最简单的完整的Activity生命周期会按照如下顺序回调:onCreate -> onStart -> onResume -> onPause -> onStop -> onDestroy。称之为entire lifetime。

    2.当执行onStart回调方法时,Activity开始被用户所见(也就是说,onCreate时用户是看不到此Activity的,那用户看到的是哪个?当然是此Activity之前的那个Activity),一直到onStop之前,此阶段Activity都是被用户可见,称之为visible lifetime。

    3.当执行到onResume回调方法时,Activity可以响应用户交互,一直到onPause方法之前,此阶段Activity称之为foreground lifetime。

    在实际应用场景中,假设A Activity位于栈顶,此时用户操作,从A Activity跳转到B Activity。那么对AB来说,具体会回调哪些生命周期中的方法呢?回调方法的具体回调顺序又是怎么样的呢?

    开始时,A被实例化,执行的回调有A:onCreate -> A:onStart -> A:onResume。

    当用户点击A中按钮来到B时,假设B全部遮挡住了A,将依次执行A:onPause -> B:onCreate -> B:onStart -> B:onResume -> A:onStop。

    此时如果点击Back键,将依次执行B:onPause -> A:onRestart -> A:onStart -> A:onResume -> B:onStop -> B:onDestroy。

    至此,Activity栈中只有A。在Android中,有两个按键在影响Activity生命周期这块需要格外区分下,即Back键和Home键。我们先直接看下实验结果:

    此时如果按下Back键,系统返回到桌面,并依次执行A:onPause -> A:onStop -> A:onDestroy。

    此时如果按下Home键(非长按),系统返回到桌面,并依次执行A:onPause -> A:onStop。由此可见,Back键和Home键主要区别在于是否会执行onDestroy。

    此时如果长按Home键,不同手机可能弹出不同内容,Activity生命周期未发生变化(由小米2s测的,不知道其他手机是否会对Activity生命周期有影响)。

    Activity高级特性

    一个进程会分配一个任务栈,只有最上面的任务栈的栈顶的Activity会被显示!

    9.png 10.png

    启动SingleInstance模式Activity的时候,会查找系统中是否存在:
    1、不存在,首先会新建一个任务栈,其次创建该Activity实例。
    2、存在,则会直接引用该实例,并且回调onNewIntent()方法。
    特殊情况:该任务栈或该实例被销毁,系统会重新创建。

    onCreate() 和 onNewIntent() 不会被同时调用。
    如果之前创建了目标Activity的实例,此时这个实例处于onPause、onStop 状态的话,再接收到intent的话,她的执行顺序为:
    onNewIntent,onRestart,onStart,onResume。

    activity栈唯一原则下,通过Intent启到一个Activity,如果系统已经存在一个实例,系统就会将请求发送到这个实例上,但这个时候,系统就不会再创建一个新的实例,不会调用onCreate方法,而是调用onNewIntent方法。
    我们需要知道,在内存吃紧的情况下,系统可能会kill掉后台运行的 Activity ,如果不巧要启动的那个activity实例被系统kill了,那么系统就会调用 onCreate 方法,而不调用 onNewIntent 方法。这里有个解决方法就是在 onCreate 和 onNewIntent 方法中调用同一个处理数据的方法,如下所示:

    public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
      getNewIntent();
    }
     
    protected void onNewIntent(Intent intent) {
      super.onNewIntent(intent);
       setIntent(intent);//must store the new intent unless getIntent() will return the old one
      getNewIntent();
    }
     
    private void getNewIntent(){
      Intent intent = getIntent(); //use the data received here
    }
    

    注意onNewIntent()中的陷阱:

    有时候,我们在多次启动同一个栈唯一模式下的activity时,在onNewIntent()里面的getIntent()得到的intent感觉都是第一次的那个数据。对,这里就是这个陷阱。因为它就是会返回第一个intent的数据。就是这么坑。

    原因就是我们没有在onNewIntent()里面设置setIntent(),将最新的intent设置给这个activity实例。

    
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);//设置新的intent
        int data = getIntent().getIntExtra("tanksu", 0);//此时的到的数据就是正确的了
    }
    

    在这里,如果你没有调用setIntent()方法的话,则getIntent()获取的intent都只会是最初那个intent

    *附:在SingleInstance启动了一个普通模式的Activity,会把新Activity加到之前的栈里,SingleInstance栈 后移;当新Activity返回时,会先返回到新Activity所在栈的剩余Activity,栈清后,才会进入SingleInstance栈,显示SingleInstance的Activity。

    相关文章

      网友评论

          本文标题:Android四大应用组件之Activity篇

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