四大组件的工作过程
一、Activity的工作过程
从startActivity方法开始分析:
①、StartActivity有好几种重载方法,但是最终调用startActivityResult()方法
②、startActivityForResult()方法(P319 ①):
因为看的是启动过程,所以只要看mParent == null部分即可。mParent指的是一个Fragment:被用来在一个界面中嵌入多个子Activity。
先注意一下mMainThread.getApplicationThread()参数->返回值是一个ApplicationThread类,ApplicationThread是ActivityThread的内部类。这两个类在启动Activity十分有用。
③、看Instrumentation.execStartActivity()方法:
发现启动Activity的真正实现是由ActivityManagerNative.getDefault()的startActivity()来完成的。
来看一下ActivityManagerNative(AMN)这个类:继承自Binder并实现IActivityManager的Binder接口。(自定义重写的IActivityManager.java文件)
ActivityManagerService(AMS)继承AMN这个类,所以AMS也是一个Binder,IActivityManager接口的实现方法在此。
再来看看ActivityMangerNative的部分代码(P321 ①),可知,AMS这个Binder对象采用单例模式向外提供,Singleton类时单例的封装类,第一次调用get()方法的时候会调用其create()方法初始化Binder对象(根据代码从ServiceManager中返回IActivityManager对象),然后查看AMS的startActivity()方法就可以了(远程调用startActivity方法)
(稍后讲解)
④、接着看一下execStartActivity()的checkStartActivityResult()(P322 ①):
作用:检查Activity的启动结果,当无法正确启动一个Activity的时候,就会抛出异常。
⑤、回到AMS的startActivity()方法中(P323 ①)
启动过程又转移到ActivitysStackSupervisor的startActivityMayWait()->startActivityLocked()->startActivityUncheckedLocked()->ActivityStack的resumeTopActivityiesLocked() 这一系列过程将启动过程转移到ActivityStack中去了。
⑥、ActivityStack的resumeTopActivityiesLocked()实现(P324 ①)
resumeTopActivity调用了resumeTopActivityInnerLocked()->ActivityStackSupervisor的startSpecificActivityLocked()
⑦、查看ActivityStackSupervisor的startSpecificActivityLocked()实现(P324 ②)
调用了realStartActivityLocked()
流程图:
⑧、realStartActivityLocked()中有一段代码(P325 ①)
注意app.thread这个对象是一个IApplicationThread类(p326 ①),根据分析IApplicationThread(是个Binder型接口)且 这个Binder接口的实现者完成了大量和Activity及Service启动和停止相关的功能。
⑨、IApplicationThread类:
ActivityThread的内部类ApplicationThread为其实现者(P328 ①),发现该类继承了ApplicationThreadNative,ApplicationThreadNative为IApplicationThread的java类(就是自动为aidl生成的java类)。最终ApplicationThread的scheduleLaunchActivity()方法启动Activity()
⑩、ApplicationThread的scheduleLaunchActivity()(P329①)
发送一个启动Acitivity的消息给Handler处理
⑪、接下来看看Handler对消息的处理(P331 ①)
根据从Handler对“LAUNCH_ACTIVITY”这个消息的处理可以知道,Activity的启动过程又ActivityThread的handleLaunchActivity()方法实现
⑫handleLaunchActivity()
通过performLaunchActivity()方法最终完成Activity的创建和启动,并且再通过handleResumeActivity()来调用被启动的Activity的onResume()方法
⑬performLaunchActivity()主要完成的事件
1.从ActivityClientRecord中获取Activity的组件的信息(P333 ①...)
2.通过Instrumentation的newActivity()方法使用类加载器创建Activity对象(P333 ② P334 ①)
3.通过LoadedApk的makeApplication()方法(P334 ②)创建Application对象(一个应用只会有一个Application对象,如果已经被创建就不会创建了),发现Application对象的创建也是通过Instrumentation完成的,当Application创建完毕的话就会通过instrumentation.callApplicationOnCreate()调用Application的onCreate()方法。
4.之后创建ComtextImp对象(P335 ①)(是Context的具体实现,重要的数据结构),通过Activity.attach()方法与Activity建立联系,同时attach()方法中完成将Activity添加进入Window的过程。
5.最后通过mInstrumentation.callActivityOnCreate(),调用Activity.onCreate()。
二、Service的工作过程
Service简介:Service具有两种工作状态,一种是启动状态(执行后台计算,无法交互),一种是绑定状态(可交互,但随着Activity的消亡而消亡)。注意的是这两种状态可以共存。
Service的启动过程
从启动状态说起
①、调用ContextWrapper.startService()(P336 ① ②)
发现调用mBase.startService()这个mBase就是ContextImpl类,就是Activity启动过程在attach()关联的对象。从mBase中看出大部分操作都是通过mBase来执行的,这种方式叫做桥接模式。
②、观察mBase.startService()(P337 ①)
调用startServiceCommon方法,通过ActivityManagerNative.getDefault()方法获取AMS(Activity中提到过).然后调用其startActivity()
③、AMS.startActivity()方法(P338 ①)
AMS会通过mServices这个对象,完成后续启动过程。mServices对象的类型是ActiveServices,是用来辅助AMS进行Service管理的类。
调用ActiveServices.startServiceLocked()方法->startServiceInnerLocked()(P338 ②)
④、 startServiceInnerLocked()
作用:描素一个Service的记录,把创建过程交给了bringUpServiceLocked()处理->realStartServiceLocked()
⑤、realStartServiceLocked()(P339 ①)
通过app.thread的sheduleCreateService()创建Service对象并调用其onCreate,之后使用sendServiceArgsLocked()调用其余方法比如(onStartCommand)
⑥、查看app.thread的sheduleCreateService()(P341 ①)
发现也是发送消息到Handler(跟Activity过程一样),之后Handler接收CREATE_SERVICE然后调用ActivityThread.handleCreateService()
⑦、ActivityThread.handleCreateService()(P341 ②)
1.通过类加载器创建Service类
2.创建Application类并调用其onCreate()
3.创建ContextImpl通过Service.attach()建立联系
4.调用Service的onCreate()将Service存储到ActivityThread中的一个列表中
5.此外ActivityThread还会通过handleServiceArgs方法调用Service的onStartCommand()(P343 ①)
Service的绑定过程
①、调用ContextWrapper的bindService()方法(P344 ①):
调用mBase.bindService(mBase同样是ContetImpl类型的对象),该方法最终调用自己的bindServiceCommom()。
②、bindServiceCommom()(P344 ②)
1.将ServiceConnection对象转化为ServiceDispatcher.InnerConnection对象。
问:为什么不能直接使用ServiceConnection?
答:因为绑定服务有可能是跨进程的(Service本身在一个进程中),所以ServiceConnection必须借助Binder才能让远程服务回调自己的方法。ServiceDispatcher的内部类InnerConnection充当了Binder这个角色。
问:ServiceDispatcher的作用?
连接ServiceConnection和InnerConnection的作用。
连接过程由LoadedApk.getServiceDispatcher方法完成
2.调用AMS的bindServiceCommon()完成Service的具体绑定过程
③、LoadedApk.getServiceDispatcher()(P345 ①)
1.在上面的代码中mServices是个ArrayMap,存储了当前活动的ServiceConnection和ServiceDispatcher的映射关系。(SC为key,SD为value)
2.系统首先会查找是否有相同的ServiceConnection,如果不存在就重新创建一个,并存储在mServices中。ServiceDispatcher内部有保存了ServiceConnection和InnerConnection对象。当Service和客户端建立连接的时候,会通过InnerConnection来调用ServiceConnection的onServiceConnected方法。(这个过程有可能是跨进程的)。当ServiceDispatcher创建完之后,getServiceDispatcher()会返回InnerConnection对象。
④、AMS的bindServiceCommon()(P347 ①)
AMS调用ActivityServices的bindServiceLocked()方法->bringUpServiceLocked()->realStartServiceLocked()(该方法运行方式与Service启动过程中的realStartServiceLocked()相似)不同的是该方法中通过app.thread.scheduleBindService(Service的启动过程的方法是app.thread.scheduleCreateService);
⑤、app.thread.scheduleBindService()(P347 ①)
同Service的启动过程,发送MSG:BIND_SERVICE给Handler,在Handler内部会调用ActivityThread的handleBindService()
⑥、ActivityThread的handleBindService()(P349 ①)
1.通过Service的token取出Service对象
2.调用Service的onBind()方法,返回一个binder(原则上来说,只要onBind()被调用就算绑定成功,但还要通知客户端。当多个客户端绑定同一个Service时,onBind()方法只会被调用一次,原因看代码)
3.调用AMS.publicService()调用客户端中ServiceConnection中的onServiceConnected()方法。
⑦、AMS.publicService()(P;349 ②)
将具体工作交给了ActiveServices的mServices对象的publishServiceLocked->c.conn.connected()
c.conn表示:ServiceDispatcher.InnerConnection
⑧、研究一下ServiceDispatcher.InnerConnection类(P350 ①)
调用了ServiceDispatcher的connected()方法
⑨、ServiceDispatcher的connected()(P350 ②)
调用mActivityThread.post(new RunConnection(name,service,0));
作用:让RunnConnection运行在主线程中
mActivityThread表示ActivityThread的Handler。
RunConnection类代表一个Runnable
⑩查看RunConnection类(P351 ①)
作用:判断Service死亡还是绑定,选择调用ServiceDispatcher的doConnected()还是doDeath()
⑪ServiceDispatcher的doConnected():调用ServiceConnection.onServiceConnected()方法
BroadcastReceiver的工作过程
一、简单使用复习
①、添加一个BroadcastReceiver(详见:BroadcastReceiver浅析)
//创建类继承BroadcastReceiver类 public class MyReceiver extends BroadcastRecevier{ public void receiver(Intent intent){ //输入代码 } } //在AndroidMaintest.xml中注册 <Recevier android:name=".MyReceiver"> <intent-filter> <action android:name="com.chen.receiver.LAUNCH"/> </intent-filter> </Receiver> //在代码中注册 MyReceiver myRecevier = new MyReceiver(); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction("com.chen.receiver,LAUNCH"); registerReceiver(myRecevier,intentFilter); //注意当用代码注册的时候需要在合适的地方接触注册 unRegisterReceiver(myRecevier); //启动BroadcastRecevier Intent intent = new Intent(); intent.addAction("com.chen.recevier.LAUNCH"); sendBroadcastRecevier(intent);
二、广播的注册过程(动态注册)
①、从registerReceiver()开始->跟Service调用方法一样交给ConextImpl.registerReceiver()->调用了自己的registerReceiverInternal()
②、ConextImpl.registerReceiverInternal()(P353 ①)
1.如果mPackageInfo存在则获取IIntentReceiver,不存在则创建IIntentReceiver
2.IntentRecevier作用:因为BroadcastRecevier是组件无法跨继承,所以产生IIntentReceiver包装BoradcastReceiver实现跨进程,向AMS发送广播注册消息。IIntentReceiver是一个Binder接口,具体实现在LoadApk.RecevierDispatcher.InnerReceiver,ReceiverDispatcher内部同时保存了BroadcastReceiver和InnerRecevier,这样当接口到广播的时候,很容易调用BraodcastRecevier的receive()方法。(发现与Service的原理相似)
3.创建IIntentReceiver过程:调用ReceiverDispathcer.getIIntentReceiver()(P355 ①)
如果该BroadcastRecevier未已被注册,则重新创建一个ReceiverDispatcher对象并保存BroadcastReceiver对象,将IIntentReciever对象作为返回值。
4.最终注册过程是由AMS的registReceiver()方法完成的(P355 ②)
最终会把InnerRecevier对象和IntentFilter对象存储起来,这样注册过程就完成了
三、发送和接收过程(普通广播)
①.调用sendBroadcast()->调用ContextImpl.sendBroadcast()->调用AMS.broadcastIntent() 直接向AMS发起异步请求用于发送广播
②、AMS.broadcastIntent()(P357 ①)
调用broadcastIntentLocked()
③、AMS.broadcastIntent() (P357 ② P358 ①)
作用1:控制广播是否要对已停止的BroadcastReceiver起作用 ,默认是不起作用的
作用2:根据intent-fileter查找出匹配的广播接收者,最终将满足的广播接收者添加到BroadcastQueue中,接着BroadcastQueue就会将广播发送给相应的广播接收者。
④、查看BroadcastQueue的发送过程(P359 ①)
发现发送给Handler一条BROADCAST_INTENT_MSG的消息,当BroadcastQueue收到消息会调用processNextBroadcast()
⑤、processNextBroadcast()(P359 ②)
发现无序广播存储在mParallelBroadcasts对象中,之后遍历该对象,调用deliverToRegisteredReceiverLocked()->内部调用了performReceiverLocked()完成具体过程
⑥、performReceiverLocked()(P360 ①)
调用app.thread(ApplicationThread)的scheduleRegisteredReceiver()
⑦、app.thread.scheduleRegisteredReceiver()(P361 ①)
调用InnerReceiver.performReceiver()->调用LoadedApk.ReceiverDispatcher.performReceiver()
⑧、LoadedApk.ReceiverDispatcher.performReceiver() (P361 ②)
创建一个Args(Runnable类),之后通过app.thread.post(Args),将其放到主线程中,等待调用
⑨、查看一下Args.run()方法(P382 ①)
发现调用了mBroadcast.recevier()方法
ContentProvider的工作过程(暂时放弃,因为连ContentProvider的使用还没弄清楚 P362)