android的四大组件
android Activity主要的生命周期:
onCreate() -> onStart() -> onResume() -> onPause() -> onStop() -> onDestory()
android 官方Activity生命周期经典图:为了重新学习,又在网上看了文章https://www.jianshu.com/p/51aaa65d5d25,自己打log测试一下记录下测试结果。
测试手机:小米8 系统版本 android 9
1.正常情况下,activity的生命周期从启动到与前台(能够与用户交互)onCreate -> onStart() -> onResume(),前台到退出app, onPause() -> onStop() -> onDestroy().
2.当从Activity处于前台,回到桌面 onPause() -> onSaveInstanceState() -> onStop().
3.设置手机可旋转屏幕,启动appActivity处于前台,旋转屏幕后调用生命周期方法onResume() -> onSaveInstanceState() -> onStop -> onDestroy() -> onCreate() -> onStart() -> onRestoreInstanceState() -> onResume(),设置了android:configChange=“orientation”仍然会走上面过程。设置了android:configChange="orientation|screenSize"旋转屏幕后不会销毁Activity重建了,没有调用生命周期方法,设置android:screenOrientation="portrait"后,屏幕不再旋转。
4.活动A启动活动B,活动A会先调用onPause(),然后活动B调用onCreate() -> onStart() -> onResume,活动B启动后,活动A在调用onSaveInstanceState() -> onStop().(目的大概是让活动B能够尽快呈现与用户交互)
以上便是有些不相似的地方(貌似意义不大,不过也记录下,可能跟android9版本或小米系统有关,条件不足,待确认)
Activity和Fragment生命周期之间的联系(这里用贴上打log图):
Activity的启动模式
1.standard(默认):标准模式,Activity默认的启动模式。以该模式启动的Activity会新建一个实例,压入启动它的Activity所在的任务栈中,不管任务栈中是否存在它的实例。注意:非Activity类型的context(ApplicationContext)没有任务栈,以这种类型的context启动标准模式Activity会导致程序崩溃。
2.singleTop:栈顶复用模式。当启动singleTop模式的Activity,会先找到当前任务栈栈顶的Acitivity是否是该Acitivity的实例,如果是就调用它的onNewInstance()方法,经测试,还会调用onResume()方法。如果不是,则新建一个实例,放到任务栈栈顶。
3.singleTask:栈内复用模式。启动singleTask模式的Acitivity,会先查看是否有它想要的任务栈,如果没有,则新建一个它要求的任务栈,并创建一个实例压入栈中。如果有它想要的任务栈,则查看栈内是否有该Activity的实例,如果没有则创建一个实例压入栈中,如果有则调用它的onNewInstance()方法和onResume()方法。
4.singleInstance:单实例模式,加强版的singleTask模式。启动单实例模式的Activity,系统会默认为它创建一个任务栈,并创建Activity实例压入栈中,该任务栈中有且只有一个Activity实例。以后调用的时候会调用它的onNewInstance(),onResume()。
Activity的Flogs
1.FLAG_ACTIVITY_NEW_TASK : 标记位设置启动的Activity为singleTask模式,经测试(效果与xml中设置不相同),网上看到(singleTask 其实等价于 new_task + clear_top + single_top),待确定。
2.FLAG_ACTIVITY_CLEAR_TOP:标记位设置启动的Activity有clear top清除在它上面Activity的效果,一般与FLAG_ACTIVITY_NEW_TASK.
3.FLAG_ACTIVITY_SINGLE_TOP:标记位设置启动的Activity为singleTop模式,效果与xml中设置效果相同.
服务 - Service
1.本地服务。服务也有它自己的生命周期,它与Activity不同的是,它有两种启动方式。不同的启动方式搜调用的生命周期方法略有不同。
第一种启动方式:
启动服务startService() 停止服务stopService() 这时它的生命周期:onCreate() -> onStartCommant() -> onStop() -> onDestroy()。服务启动后便和启动者没有关系了,并且多次启动也不会重新创建一个新的服务,会调用onStartCommant(). 调用stopService()会停止服务。因为服务启动后与启动着没有关系了,所以即使启动者(例如Activity)被退出了,服务也会不停止,甚至退出APP。除非调用stopService()停止服务或者杀死进程。
第二种启动方式:
bindService(...); unBindService(...);这种启动方式一般是Activity启动Service,Activity绑定Service,方便它们之间的通信。这种启动方式下的服务,在绑定它的Activity被杀死后,它也会停止。一般需要在Activity的onDestroy()中添加unBindService(...).
2.远程服务
远程服务一般是指其它进程的服务。要与远程进程进行通信典型的做法是使用aidl,可以在另一个App中添加一个服务作为远程服务,也可以在同一个项目中将服务设置在一个单独的进程中,它们本质上是一样的东西。借助网上的例子并自己码一遍加深印象。
客户端代码:
服务端代码:
代码结构
广播 - BoradcastReceiver
广播有普通广播(无序广播),有序广播,粘性广播。
广播有两种注册方式:静态注册和动态注册。
静态注册就是在ActivityMenifest.xml中注册声明,静态注册在进程被杀死的情况下也能接收到广播。动态注册就是在代码中注册广播。动态注册广播注册方式需要在代码中注册了才能接受到广播,并且应该在适当的时机取消注册(譬如onPause())。
动态注册:
动态注册
动态注册
静态注册的发送接收广播跟动态注册是一样的,只需要将action设置为静态广播过滤的action即可。
静态注册
注意事项:广播接收器中不能做耗时操作,程序的执行时间是10秒内,否则会弹出ANR(Application No Response)的对话框。一般来说,广播接收器中处理的事情都是比较轻量,耗时操作可以开启一个服务去进行操作。
enabled代表是否启用这个广播接收器,exported属性表示是否允许这个广播接收器接受本程序以外的广播。
内容提供者 - ContentProvider
内容提供者,可以对手机的存储数据进行操作,可以是手机系统本身的资源,也可以是其它app的数据。内容提供者是天生的进程通信的组件。