本文已经收录到个人
Github
我的博客,欢迎大佬们光临寒舍:html个人GIthub博客git
Activity
的工做过程Service
的工做过程
Service
的启动过程Service
的绑定过程
BroadcastReceiver
的工做过程
BroadcastReceiver
的注册过程BroadcastReceiver
的发送和接收过程
ContentProvider
的工做过程何为“四大”:github
Activity
Service
BroadcastReceiver
ContentProvider
谈到四大组件,相信在座各位都再熟悉不过了,光闻其名,未见其声,“四大”二字一出,足见其在安卓系统中的地位,可谓是安卓界的F4
。面试
其地位之崇高,在某种程度上也能够体现他的重要性,因此说,光会使用四大组件仍是不能体现咱们对他的重视(ai hu)的,咱们还要分析其工做过程,可以更好地理解系统内部的运行机制,从而加深对Android
体系结构的认识;同时,四大组件仍是面试必问的知识点之一。数据库
综上,掌握好四大组件相关的知识,对于一个Android
开发者来讲是很是重要的!ide
如下内容紧张赤鸡,请系好保险带,咱们要开车(hu you)了。— No picture,say a J8!post
Activity
类型:展现型组件学习
做用:展现一个界面并和用户交互测试
使用:this
A.须要在AndroidManifest
中注册
B.须要借助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);
standard
:标准模式singleTop
:栈顶复用模式singleTask
:栈内复用模式singleInstance
:单实例模式想了解启动模式的读者,能够看下笔者写的一篇文章:进阶之路 | 奇妙的Activity之旅中的
2.2
部分
finish()
结束一个Activity
Service
类型:计算型组件
做用:在后台执行一系列计算任务,耗时的后台计算建议在单独的线程中执行
使用:
A.须要在AndroidManifest
中注册
B.须要借助Intent
启动:Intent intent = new Intent(xxx.this, xxx.class); startService(intent);
C.两种运行状态:
- 启动状态:经过
startService()
- 绑定状态:经过
bindService()
D.中止方式:unBindService();stopService();
BroadcastReceiver
两种注册方式:
A.动态注册:经过
Context.registerReceiver()
&Context.unRegisterReceiver()
,必需要启动应用才能注册并接收广播。B.静态注册:在
AndroidManifest
文件中注册,不须要启动应用便可接收广播。须要借助
Intent
发送广播:Intent intent = new Intent("xxx"); sendBroadcast(intent);
四种广播类型:
A.普通广播
B.有序广播
C.本地广播
D.粘性广播
ContentProvider
IPC
的一种方式)
须要在
AndroidManifest
中注册无需借助
Intent
启动四种操做:注意须要处理好线程同步(由于这些操做运行在
Binder
线程)A.
insert()
:添加数据B.
update()
:更新数据C.
delete()
:删除数据D.
query()
:查询数据
想详细了解
IPC
机制的读者,能够看下笔者写的一篇文章:进阶之路 | 奇妙的 IPC 之旅
差很少该进入今天的主题了,为了逼格,为了高薪,大伙往前冲!
Activity
Activity
启动过程流程图:
一眼看上去有点晕晕的,墙裂建议配合源码一块儿服用,效果极佳,笔者推荐一篇文章:图解Activity启动流程,进阶高级
Q1:结论:
ActivityManagerService
、ApplicationThread
都是Binder
Application
的建立也是经过Instrumentation
来完成的,这个过程和Activity
对象同样,都是经过类加载器来实现的Activity
的启动过程最终回到ApplicationThread
中,经过ApplicationThread.scheduleLaunchActivity()
将启动Activity
的消息发送并交由Handler H
处理。Handler H
对消息的处理会调用handleLaunchActivity()
->performLaunchActivity()
得以最终完成Activity的建立和启动。Q2:重点类:
Instrumentation
:
instrumentation
是Android
系统里面的一套控制方法或者”钩子“。 这些钩子能够在正常的生命周期(正常是由操做系统控制的)以外控制Android
控件的运行;它们同时能够控制Android
如何加载应用程序。
ActivityManagerService「AMS」
:
AMS
是系统的引导服务,应用进程的启动、切换和调度、四大组件的启动和管理都须要AMS
的支持。
ActivityStackSupervisor
:
ActivityStackSupervisor
在AMS
中的构造方法中被建立。
AMS
经过操做ActivityStackSupervisor
来管理Activity
ActivityStack
:
ActivityStack
从名称来看是跟栈相关的类,其实它是一个管理类,用来管理系统全部Activity
的各类状态- 它由
ActivityStackSupervisor
来进行管理的
ApplicationThread
:
ActivityThread
的私有内部类,也是一个Binder
对象- 在此处它是做为
IApplicationThread
对象的Server
端,等待Client
端的请求而后进行处理,最大的Client
就是AMS
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()
去完成。BroadcastReceiver
源码流程分析:BroadcastReceiver 的工做过程分析
四大组件的静态注册都是在应用安装时由
PackageManagerService(PMS)
解析注册,当动态注册BroadcastReceiver
时流程为:
结论:
AMS
,并把远程Receiver
( 实际上传的是IIntentReceiver
,是个Binder
对象)和远程IntentFilter
保存起来,完成注册任务
FLAG_EXCLUDE_STOPPED_PACKAGES
:广播不会发送给已经中止的APP
(系统为全部广播默认添加该标记)FLAG_INCLUDE_STOPPED_PACKAGES
:广播也会发送到已经中止的APP
(两个标记共存时,以该标记为准)
ReceiverDispatcher .performReceive ()
里回调了Receiver
的onReceive()
,使得广播得以接收并处理Q2:实现原理:
从实现原理看上,广播使用了观察者模式,基于消息的发布/订阅事件模型
具体实现流程要点粗略归纳以下:
BroadcastReceiver
经过Binder
机制向AMS
进行注册Binder
机制向AMS
发送广播AMS
查找符合相应条件(IntentFilter
/Permission
等)的BroadcastReceiver
,将广播发送到BroadcastReceiver
(通常状况下是Activity
)相应的消息循环队列中BroadcastReceiver
中的onReceive()
方法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()
的实现原理和query()
相似,限于篇幅,这里不展开,感兴趣的读者能够主动去探究源码流程分析:ContentProvider的工做过程
结论:
ContentProvider
的multiprocess
属性:ContentProvider
是不是单例,通常用单例
访问ContentProvider
须要ContentResolver
,其真正实现类是ApplicationContentResolver
。当ContentProvider
所在进程未启动时,第一次访问它会触发ContentProvider
的建立以及进程启动
当ContentProvider
所在的进程启动时,会同时被启动并被发布到AMS
中
注意:
ContentProvider.onCreate()
要先于Application.onCreate()
执行
ActivityThread.handleBindApplication()
完成ContentProvider
的建立。恭喜你!已经看完了前面的文章,相信你对
四大组件
已经有必定深度的了解,下面,进行一下课堂小测试,验证一下本身的学习成果吧!
Q1:为何要使用ContentProvider
?它和SQL
在实现上有什么区别?
ContentProvider
屏蔽了数据存储的细节,内部实现透明化,用户只需关心URI
便可(是否匹配)ContentProvider
能实现不一样APP
的数据共享,SQL
只能是本身程序才能访问ContentProvider
还能增删本地的文件,XML
等信息Q2:Android
引入四大组件的用意
这个问题在笔者刚开始学习
Android
的时候就一直困惑,直到看了一篇Google Android 团队:Dianne Hackborn发表在Google+
上的一篇post
的译文
看法:Google Android Framework
团队决定,不要让一个明确的Main
方法做为APP
的入口,由于须要让系统对APP
怎样运行有更多的控制权,在该系统中,用户永远不须要考虑开启和中止一个APP
,而把这些事交给系统去管理。因此他们设计了四大组件以做为APP
功能的载体和入口:
Activity
一个
APP
与用户交互的入口
BroadcastReceiver
- 一种让系统在正常的用户流(
user flow
)以外,传递事件给APP
的机制。- 最重要的是,由于这是另外一个被精心定义的
APP
的入口,即便APP
当前并不在运行,系统也能够将Broadcasts
传递给APP
。
Service
当
APP
因为各类各样的缘由须要在后台运行时,Service
就是一个这样的入口
ContentProvider
- 人们一般会将它看成对数据库的抽象,由于有许多的
API
和支持库就是这样使用ContentProvider
的- 可是从系统设计的角度,这并非
ContentProvider
的初衷。对于系统来讲,ContentProvider
其实是一个入口,用于获取一个APP
内部的公开的被命名的数据项(data items
),每一个数据项都被一个URI scheme
所标识。
若是文章对您有一点帮助的话,但愿您能点一下赞,您的点赞,是我前进的动力
本文参考连接: