要点提炼|开发艺术之四大组件
2017-12-27 本文已影响1972人
厘米姑娘
提到四大组件大家肯定再熟悉不过了,本篇侧重于对四大组件工作过程的分析:
- 概述
- 工作过程
- Activity
- Service
- BroadcastReceiver
- ContentProvider
1.概述
a.Activity
- 类型:展示型组件。
- 作用:展示一个界面并和用户交互。
- 使用:
- 需要在AndroidManifest中注册。
-
需要借助Intent启动,两种方式:
- 显示Intent:
Intent intent=new Intent(xxx.this,xxx.class); startActivity(intent);
- 隐式Intent:
Intent intent=new Intent(); intent.setAction(xxx); intent.addCategory(xxx); startActivity(intent);
- 显示Intent:
- 四种启动模式:
- standard:标准模式
- singleTop:栈顶复用模式
- singleTask:栈内复用模式
- singleInstance:单实例模式
- 对用户而言是可见的。
- 通过
finish()
结束一个Activity。
相关基础:入门之Activity篇、开发艺术之Activity
b.Service
- 类型:计算型组件。
- 作用:在后台执行一系列计算任务,耗时的后台计算建议在单独的线程中执行。
- 使用:
- 需要在AndroidManifest中注册。
-
需要借助Intent启动:
Intent intent = new Intent(xxx.this, xxx.class); startService(intent);
- 两种运行状态:
- 启动状态:通过
startService()
- 绑定状态:通过
bindService()
- 启动状态:通过
- 用户无法感知。
- 通过
unBindService()
和stopService()
完全停止一个Service。
相关基础:入门之Service篇
c.BroadcastReceiver
- 类型:消息型组件。
- 作用:在不同的组件乃至不同的应用之间传递消息。
- 使用:
- 两种注册方式:
- 动态注册:通过
Context.registerReceiver()
&Context.unRegisterReceiver()
,必须要应用启动才能注册并接收广播。 - 静态注册:在AndroidManifest文件中注册,不需要启动应用即可接收广播。
- 动态注册:通过
-
需要借助Intent发送广播:
Intent intent = new Intent("xxx"); sendBroadcast(intent);
- 四种广播类型:
- 普通广播
- 有序广播
- 本地广播
- 粘性广播
- 用户无法感知。
- 没有停止概念。
- 两种注册方式:
d.ContentProvider
- 类型:共享型组件。
- 作用:向其他组件乃至其他应用共享数据。
- 使用:
- 需要在AndroidManifest中注册。
- 无需借助Intent启动。
- 四种操作:注意需要处理好线程同步
-
insert()
:添加数据 -
update()
:更新数据 -
delete()
:删除数据 -
query()
:查询数据
-
- 用户无法感知。
- 无需手动停止。
相关基础:入门之ContentProvider篇、IPC方式之ContentProvider
考考自己:android四大组件的运行状态
二.工作过程
由于相关源码非常多,这里借用@amurocrash的UML图来提炼流程更为直观,另附相关源码分析的文章供大家详细了解。
a.Activity
Activity启动过程流程图:
Activity启动过程结论:
- ActivityManagerService、ApplicationThread都是Binder。
- Application的创建也是通过Instrumentation来完成的,这个过程和Activity对象一样,都是通过类加载器来实现的。
- Activity的启动过程最终回到ApplicationThread中,通过
ApplicationThread.scheduleLaunchActivity()
将启动Activity的消息发送并交由Handler H处理。 - Handler H对消息的处理会调用
handleLaunchActivity()
->performLaunchActivity()
得以最终完成Activity的创建和启动。
源码分析:Activity的工作过程
b.Service
- Service启动过程流程图:
- Service绑定过程流程图:
结论:
-
ContextImpl是Context的具体实现,通过
Activity.attach()
和Activity建立关联。Activity.attach()
中还会完成Window的创建并和Activity&Window的关联,由此事件可传递给Window。 - ActivityServices是一个辅助ActivityManagerService(AMS)进行Service管理的类,包括Service的启动、绑定和停止。
- 和Activity类似的,Service的启动/绑定过程最终回到ApplicationThread中,通过
ActivityThread.handleCreateService()
/ActivityThread.handleBindService
完成Service的启动/绑定,注意绑定Service的后续还必须 告知客户端已经成功连接Service 的这一流程,由ActivityManagerService.publishService()
去完成。
源码分析: Service的工作过程
c.ContentProvider
- ContentProvider启动过程流程图:
- 启动的入口为
ActivityThread.main()
:创建ActivityThread实例并创建主线程消息队列;- ->
ActivityThread.attach()
:远程调用AMS.attachApplication()
并提供ApplicationThread用于和AMS的通信;- ->
AMS.attachApplication()
:通过ActivityThread.bindApplication()
方法和Handler H来调回ActivityThread.handleBindApplication()
;- ->
ActivityThread.handleBindApplication()
:先创建Application、再加载ContentProvider、最后回调Application.onCreate()
。
图片来源:四大组件的工作过程
- Query过程流程图:
insert()
、delete()
和update()
类似,这里不展开
结论:
- ContentProvider的multiprocess属性:ContentProvider是否是单例,一般用单例。
- 访问ContentProvider需要ContentResolver,其真正实现类是ApplicationContentResolver。当ContentProvider所在进程未启动时,第一次访问它会触发ContentProvider的创建以及进程启动。
- 当ContentProvider所在的进程启动时,会同时被启动并被发布到AMS中。注意:
ContentProvider.onCreate()
要先于Application.onCreate()
执行。 - 同样的,最终通过
ActivityThread.handleBindApplication()
完成ContentProvider的创建。
源码分析: ContentProvider的工作过程
d.BroadcastReceiver
- 四大组件的静态注册都是在应用安装时由PackageManagerService(PMS)解析注册,当动态注册Service时流程为:
- 广播发送和接收过程流程图:
结论:
- 动态注册广播最终会跨进程交给AMS,并把远程Receiver( 实际上传的是IIntentReceiver,是个Binder )对象和远程IntentFilter保存起来,完成注册任务。
- 发送广播时,系统为intent添加了两个标记位:
- FLAG_INCLUDE_STOPPED_PACKAGES :广播也会发送到已经停止的APP(两个标记共存时,以该标记为准)
- FLAG_EXCLUDE_STOPPED_PACKAGES :广播不会发送给已经停止的APP(系统为所有广播默认添加该标记)
- 最终在
ReceiverDispatcher .performReceive ()
里回调了Receiver 的onReceive()
,使得广播得以接收并处理。
源码分析: BroadcastReceiver 的工作过程
希望这篇文章对你有帮助~