Activity的生命周期函数、onActivityResult、intent和启动模式的调用关系

来源:互联网 发布:淘宝达人网页 编辑:程序博客网 时间:2024/06/03 14:39

前段时间被activity的启动模式和intent传值问题纠结了不少时间,有必要进行一下总结和学习,日后也好回来复习,下图中MainActivity简称A,TwoActivity简称B。

一.activity A和B启动模式都是默认(即没在manifest文件中设置),调用startActivity函数

     在这样情况下,从A跳转到B,在B中点击返回键,执行的生命周期函数分别是


    这种情况是没有任何疑问的,我们应该都清楚。


二.activity A和B启动模式都是默认(即没在manifest文件中设置),调用startActivityForResult函数

     在这种情况下,从A跳转到B,在B中点击返回键,执行的生命周期函数分别是


     可见,onActivityResult方法在A的onResume方法之前,同时也在A的onRestart和onStart方法之前(本人之前没注意onActivityResult和onResume先后顺序,导致浪费了好多时间)。


三.activity A设置为singleTop或者singleTask,B保持默认模式,调用startActivityForResult

     在这种情况下,从A跳转到B,在B中点击返回键,执行的函数顺序为


     因此,A的设置为这两种启动模式不影响正常的函数执行顺序。


四.activity A保持默认,B设置为singleTop,调用startActivityForResult

     在这样情况下,从A跳转到B,在B中点击返回键,执行的函数顺序为


     因此,函数执行顺序正常。


五.activity A设置为默认,singleTop或者singleTask,B设置为singleTask或者singleInstance,调用startActivityForResult

     在这样情况下,从A跳转到B,在B中点击返回键,执行的函数顺序为


    由此可见,在B刚刚跳转的时候A的onActivityResult方法已经调用了,并没有等到B的返回结果后再调用,并且A执行了onResume方法后才调用B的一系列创建和显示函数,从B返回后,函数执行顺序正常。


六.activity A设置为默认或者singleTop,B设置为默认或者singleTop,AB之间互相调用startActivity方法,打印出A的getIntent()结果


     由此看出,A第一次获得了主Activity的intent,第二次重新创建了A,获得了B传过来的intent。


七.activity A设置为singleTask,B设置为默认,AB之间互相调用startActivity方法,打印出A的getIntent()结果


     由此可见,activity A获得的两次intent都是一样的,并没有获得从B跳转过来的intent。


总结:

1.针对第五中的情况,将activity B设置为singleTask或者singleInstance,A的onActivityResult会提前执行,B中的setResult函数不起作用。查阅了相关资料后发现,当activity B为singleTask或者singleInstance时,只能用startActivity方法,Android认为不同task之间不能传递数据。其实这样的说法不太令人接受,更清楚的解释是,如果task 1里面的activity 1跳转到task 2里面的某个指定为singleTask的activity 2,那么task 2里面的activity会全部加载到当前的task 1里面(上面),因此从activity 2返回后,不一定会回到task 1,因此setResult也就没意义了,出于系统保护机制,onActivityResult方法就立即执行了。因此,将singleTask改为默认模式,就可以避免这样的情况。


2.针对第七中的情况,当要携带数据跳转到singleTask的activity时,由于task中只存在一个实例,因此不会执行onCreate方法,但是会执行A的onNewIntent方法,此时需要在该方法内调用setIntent方法将intent赋值给A的intent,否则A中的intent仍然是老的intent,正如第七中的所示。从另一层面讲,指定为singleTask的activity,往往会被很多activity调用,因此onNewIntent方法就是为了区分来自不同activity的intent数据。加完setIntent方法后运行结果如下所示


  此时,activity A中获取的intent就是两个不一样的了。


以上只是笔者自己的测试和理解,如有不到之处还望指出,共勉之。