四大组件的工作过程

一、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);
Broadcast的简单使用

二、广播的注册过程(动态注册)

①、从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)

 

posted @ 2016-05-05 17:13  技术丶从积累开始  阅读(859)  评论(0编辑  收藏  举报