四大组件之一,Activity 提供窗口来和用户进行交互,开发者可以通过setContentView把UI放到窗口上显示
Android中的activity全都归属于task管理,task 是多个 activity 的集合,这些 activity 按照启动顺序排
队存入一个栈(即“back stack”)。android默认会为每个App维持一个task来存放该app的所有activity,task的默认name为该app的packagename。但是一个Task是可以由一个应用或者多个应用的Activity组成的。比如我们可以通过一个Activity跳转到另一个第三方的Activity,所以说这两个应用的Activity在一个Task中。
我们也可以在AndroidMainfest.xml中申明activity的taskAffinity属性来自定义task,但不建议使
用,如果其他app也申明相同的task,它就有可能启动到你的activity,带来各种安全问题。
Task是跨应用的,不属于任何一个应用
就是task的名称,表示activity到底要放在哪个task里面
如果不标注,表示就是包名,如果带了affinity,activity就会启动到这个名称下的栈中里面,下面红框中就是affinity
adb shell dumpsys activity activities | sed -En -e '/Stack #/p' -e '/Running activities/,/Run #0/p'
我们可以通过Launcher、通知、第三方应用scheme
图片来自https://developer.android.google.cn/guide/components/activities/activity-lifecycle
打开一个Activty:onCreate、onStart、onResume
这时是运行状态
退出一个Activity: onPause、onStop、onDestory
其中可见的状态是在onStart和onStop之间,可交互的状态是onResume和onPause之间
需要注意的是:
onCreate与onStart的区别:
onStart与onResume的区别
onPause与onStop的区别
onStop和onDestory的区别
为了实现一些默认启动(standard)模式之外的需求:
当通过这种模式来启动Activity时,
Android为目标 Activity创建一个新的实例,并将该Activity
添加到当前Task栈中。这种方式不会启动新的Task,只是将新的 Activity添加到原有的Task中。
这里需要注意的是:
该模式和standard模式基本一致,但有一点不同:当将要被启动的Activity已经位于Task栈顶时,系统
不会重新创建目标Activity实例,而是直接复用Task栈顶的Activity。即:栈顶复用模式
应用场景:
Activity在同一个Task内只有一个实例。
如果将要启动的Activity不存在,那么系统将会创建该实例,并将其加入Task栈顶;
如果将要启动的Activity已存在,且存在栈顶,直接复用Task栈顶的Activity。
如果Activity存在但是没有位于栈顶,那么此时系统会把位于该Activity上面的所有其他Activity全部移
出Task,从而使得该目标Activity位于栈顶。即:栈内复用模式
应用场景:
MainActivity: 当我们从MainActivity跳转到多级子页面后,想要跳回MainActivity并将之前打开的Activity出栈。
无论从哪个Task中启动目标Activity,只会创建一个目标Activity实例且会用一个全新的Task栈来装载
该Activity实例(全局单例).
如果将要启动的Activity不存在,那么系统将会先创建一个全新的Task,再创建目标Activity实例并将该
Activity实例放入此全新的Task中。
如果将要启动的Activity已存在,那么无论它位于哪个应用程序,哪个Task中;系统都会把该Activity所
在的Task转到前台,从而使该Activity显示出来。
应用场景:锁屏页面、来电页面等
Intent i = new Intent(this,NewActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
两种方式的区别:
在Manifest中定义是面向创建者的, 使用Intent.setFlags是面向调用者,调用者想让所启动的Activity按照自己的意愿启动
需要注意的是:
A跳转B
A:onPause
B:onCreate-onStart-onResume
A:onStop
B返回A
B:onPause
A:onRestart-onStart-onResume
B:onStop-onDestory
A是singleTop,A跳转A
onPause-onNewIntent-onResume
在栈顶时不会创建A的实例
A是singleTask,A跳转A和 singleTop是一样的生命周期
onPause-onNewIntent-onResume
A跳转B再跳转A
A:onPause
B:onCteate-onStart-onResume
A:onStop
B:onPause
A:onRestart-onStart-onNewIntent-onResume
B:onStop-onDestory
可以看到当A在栈中存在时,再次跳转不会创建A的实例并使A上面的B出栈
无论从哪个Task中启动目标Activity,只会创建一个目标Activity实例且会用一个全新的Task栈来装载
该Activity实例(全局单例).
B是singleInstance A和C是standard
A跳转B再跳转C,生命周期和standard一样,需要注意的是:
为了避免系统回收Activity造成数据丢失,Android提供了onSaveInstanceState(Bundle outState)和onRestoreInstanceState(Bundle savedInstanceState)用于保存和恢复数据
onSaveInstanceState在Activity可能被系统回收的情况下调用
需要注意的是:
onRestoreInstanceState只有在Activity被系统回收的了,重新创建Activity的时候才调用
比如上一节横竖屏切换的生命周期显示在onStart后调用了onRestoreInstanceState,因为横竖屏切换时伴随着Activity的回收和创建
Activity、services、BroadcastReceiver都是通过intent传递消息的。
在 Android 的 AndroidManifest.xml 配置文件中可以通过 intent-filter 节点为一个 Activity 指定其
Intent Filter的过滤信息,以便告诉系统该 Activity 可以响应什么类型的 Intent。
intent-filter的过滤信息有:action、category、data。
需要注意的是
一个 Intent Filter 可以包含多个 Action,Action 列表用于标示 Activity 所能接受的“动作”,它是一个用
户自定义的字符串。
……
在代码中就可以使用,
action 列表中包含了“com.himi.myaction”的 Activity 都将会匹配成功
Intent intent=new Intent();
intent.setAction("com.himi.myaction");
action的匹配要求是:intent中必须有一个action,而且这个action必须和intent-filter中的一个action相同
category也是一个字符串。
它的匹配规则是:intent中如果有category,不管有几个category,那么必须是intent-filter中定义的category。
intent中可以不设置category,系统会默认在startActivity或者startActivityForResult的时候添加category:“android.intent.category.DEFAULT”
所以只有在intent-filter中配置了
才会接受到隐式调用
data匹配要求是:如果intent-filter中定义了data,intent中必须有一个data,而且这个data必须和intent-filter中的一个data相同
data有两部分构成:URI和mimeType
URI的结构是:
://:/[||]
比如:
content://com.himi.project:8888/folder
下面进行使用举例
Intent intent = new Intent("com.himi.action.module1");
intent.addCategory("com.himi.category.c1");
intent.setData(Uri.parse("test1://himi"));
startActivity(intent);
或者使用
Intent intent = new Intent("com.himi.action.module2");
intent.addCategory("com.himi.category.c22");
intent.setData(Uri.parse("test://gogogo"));
startActivity(intent);
mimeType是指媒体类型,比如image/jpeg、video/*等
前台进程>可见进程>service进程>后台进程>空进程
本文用于总结和学习
如有错误,欢迎指正
如果本文对你有帮助,麻烦点个赞或收藏哦
感谢