Android的四大钻无论对开发者或是用户都意义重大,对于用户来说应用就是Activity,用户所能看到的和交互的都发生在Activity中,对于开发者来说四大组件更是开发功能个展示功能的基础和媒介,对于初级开发者每天的工作都在和四大组件打交道,它也成为初级开发者成长的重要一关,本文就从过年源码的角度分析下四大组件的启动过程;
1、Activity启动过程
Activity是我们打交道最多的组件,也是初学者接触最早的组件,特的使用范围和频率也最多,使用如此频繁的Activity你究竟了解多少呢?下面从源码的角度一起分析一下Activity的启动过程,在分析源码之前先介绍两个系统服务接口IActivityManager和IApplicationThread,它们都是在服务端只用Binder通信,(关于BinderAndroid进阶知识树——Android 多进程、Binder 你必须知道的一切)具体在本地的两个代理类如下:
- IApplicationThread
class ApplicationThread extends IApplicationThread.Stub{…...}
- IActivityManager
class ActivityManagerService extends IActivityManager.Stub{……}
由上面的两个代理类知道,系统中使用AIDL实现客户端和服务端的通信,介绍这两个代理类后,这里先介绍下程序在IActivityManager中如何与IApplicationThread交互的,开发者都知道Android程序的开始会执行ActivityThread.main()方法,在main()中创建了ApplicationThread实例并完成了在Ams中的设置
final ApplicationThread mAppThread = new ApplicationThread(); // 实例化ApplicaitonThread
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);//main()中调用attach()
private void attach(boolean system, long startSeq) {
final IActivityManager mgr = ActivityManager.getService();
mgr.attachApplication(mAppThread, startSeq);
}
在main()方法中调用了attach(),attach()中通过ActivityManager.getService()获取IActivityManager接口的代理类AMS,然后调用AMS.attachApplication()传入mAppThread对象;
@Override
public final void attachApplication(IApplicationThread thread, long startSeq) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
}
}
在attachApplication中调用attachApplicationLocked()传入thread对象,attachApplicationLocked中调用了ProcessRecord.makeActive()在内部保存thread,这样AMS中就持有了ApplicationThread中代理的Binder对象;
app.makeActive(thread, mProcessStats); //
public void makeActive(IApplicationThread _thread, ProcessStatsService tracker) {
thread = _thread;
}
上面实现了AMS和ApplicationThread的通信,那下面开始进入Activity的启动过程分析;
- 执行启动Activity
startActivity()
Activity的启动是从一句startActivity()开始的,无论是否使用RequestCode启动,启动过程最终都会调用Activity的startActivityForResult()
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
}
}
startActivityForResult()中调用会调用Instrumentation.execStartActivity(),Instrumentation在程序的启动和Activity的启动中起着重要的作用,而且在插件化中通过Hook系统中的Instrumentation对象还可以实现更多的功能,本篇指分析和Activity启动相关的
- execStartActivity()
int result = ActivityManager.getService() //1
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent); //2、检查Activity的启动结果
- 注释1处调用IActivityManager代理类,IActivityManager是系统的服务接口,在此处采用Binder通信,ActivityManager.getService() 获取到的是它代理实现类ActivityManagerService,然后调用ActivityManagerService.startActivity()方法启动活动
- 在AMS启动活动后,调用checkStartActivityResult()检查启动结果,会根据具体的失败原因抛出异常
- ActivityManager.getService():获取IActivityManager的代理类
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
此处参照Android 8.1 源码,在系统中IActivityManager使用Singleton封装单例提供,在getService()中通过IActivityManagerSingleton.get()获取,get()会调用Singleton的create()通过ServiceManager获取对应的Binder,在根据Binder获取代理对象即ActivityManagerService对象,到此程序进入AMS中
- AMS中的startActivity()中经过一系列的调用代码最终执行到ActivityStackSupervisor的realStartActivityLocked(),realStartActivityLocked中调用IApplication接口方法处理LaunchActivity
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info,
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, !andResume,
mService.isNextTransitionForward(), profilerInfo);
此处IApplication接口的代理类为ApplicationThread,也就是方法最终进入ApplicationThread类中,ApplicationThread为ActivityThread中的内部类,它通过Handler发送消息方式与ActivityThread通信;
@Override
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
int procState, Bundle state, PersistableBundle persistentState,
List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
ActivityClientRecord r = new ActivityClientRecord();
.......
r.overrideConfig = overrideConfig;
sendMessage(H.LAUNCH_ACTIVITY, r);
}
ApplicationThread中创建ActivityClientRecord对象保存活动信息,然后发送Handler消息,handler消息最终被ActivityThread中的Handler子类H所消耗,在H的handleMessage()中最终调用ActivityThread中startActivityNow()方法;
- ActivityThread的startActivityNow()来启动Activity
public final Activity startActivityNow(){
ActivityClientRecord record = new ActivityClientRecord()// 1
r.token = token;
r.ident = 0;
r.intent = intent;
r.state = state;
r.parent = parent;
r.embeddedID = id;
r.activityInfo = activityInfo;
r.lastNonConfigurationInstances = lastNonConfigurationInstances;
return performLaunchActivity(r, null);//2
}
在startActivityNow()中,首先创建ActivityClientRecord保存activity启动信息,然后直接调用performLaunchActivity()启动活动,performLaunchActivity方法至关重要,Activity的一系列的初始化都在其中完成;
1.1、performLaunchActivity()
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ContextImpl appContext = createBaseContextForActivity(r); //1、
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); //2、调用Instrumentation实例的方法
Application app = r.packageInfo.makeApplication(false, mInstrumentation); //3、创建了Application并调用onCreate()初始化
instrumentation.callApplicationOnCreate(app);
//4
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback);
//5
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
r.setState(ON_CREATE);
}
performLaunchActivity()方法中执行了很多我们熟悉的过程:
- . 从ActivityClientRecord中获取Activity的信息
- . 创的ContextImpl实例并完成与Activity绑定,此处就是Activity中使用的context(详情见Android插件化——Context机制)
- . 使用ClassLoader并调用Instrumentation.newActivity()中方法创建Activity的实例
public Activity newActivity(ClassLoader cl, String className,
Intent intent)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
String pkg = intent != null && intent.getComponent() != null
? intent.getComponent().getPackageName() : null; //获取Package
return getFactory(pkg).instantiateActivity(cl, className, intent);
}
public @NonNull Activity instantiateActivity(@NonNull ClassLoader cl, @NonNull String className,
@Nullable Intent intent)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
return (Activity) cl.loadClass(className).newInstance(); //使用classLoader加载Class并创建实例
}
- . 创建Application实例,并调用Application.create()完成成序的初始化
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
appClass = "android.app.Application";
try {
java.lang.ClassLoader cl = getClassLoader();
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
app = mActivityThread.mInstrumentation.newApplication( //调用Instrumentation创建Application
cl, appClass, appContext);
appContext.setOuterContext(app);
}
mActivityThread.mAllApplications.add(app);
mApplication = app;
if (instrumentation != null) {
try {
instrumentation.callApplicationOnCreate(app); //调用application的onCreate()
}
}
return app;
}
在创建Application过程中:
- 赋值appClass指向要执行的类android.app.Application
- 创建Application 中的ContextImpl对象
- 调用mInstrumentation.newApplication()实例化Application,并执行attach()绑定Context
static public Application newApplication(Class<?> clazz, Context context){
Application app = (Application)clazz.newInstance();
app.attach(context);
return app;
}
- 执行Application的onCreate()
- . 调用Activity的attach()完成Window的创建个初始化
- attach()中创建了PhoneWindow 然后setContentView后有初始化DecorView,加载布局和视图,详情点击Android进阶知识树——Window & ViewRootImpl
- . 调用onCreate()完成Activity的初始化
在执行onCreate方法之后,Activity的启动就完成了,可此时Activity的内容只是添加到attach()中创建的PhoneWindow中了,但此时的PhoneWindow并为显示在界面上,PhoneWindow的真正添加显示的过程实在处理resume()方法中,详细点击查看上面的Window & ViewRootImpl的连接;
2、Service的启动过程
2.1、 startService():启动服务
@Override
public ComponentName startService(Intent service) {
return mBase.startService(service); //mBase是ContextImpl的实例
}
startService()中直接调用mBase中的方法,此处的mBase是Activity中的启动过程中创建的ContextImpl对象,他在执行attach是会和Activity绑定并赋值父类的mBase,所以此处调用的是ContextImpl中的方法
- ContextImpl.startService()
@Override
public ComponentName startForegroundService(Intent service) {
return startServiceCommon(service, true, mUser);
}
private ComponentName startServiceCommon(Intent service, boolean requireForeground,
UserHandle user) {
try {
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
getContentResolver()), requireForeground,
getOpPackageName(), user.getIdentifier());
return cn;
}
}
在startService()直接调用startServiceCommon()方法,startServiceCommon中用同样的方法获取AMS对象,并调用AMS的startActivity对象,AMS中会继续调用ActivityServices中的startServiceLocked()创建ServiceRecord记录服务信息,然后调用startServiceInnerLocked(),startServiceInnerLocked()中又调用bringUpServiceLocked()最终程序执行到realStartServiceLocked()方法中
- realStartServiceLocked()
app.thread.scheduleCreateService(r, r.serviceInfo,
mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
app.repProcState);
realStartServiceLocked()中用同样的方法调用IApplication中方法,由上面分析知道执行的是代理类ApplicationThread中的scheduleCreateService()方法,scheduleCreateService中同样使用Handler机制调用ActivityThread中的放啊
public final void scheduleCreateService(IBinder token,
ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
updateProcessState(processState, false);
CreateServiceData s = new CreateServiceData();
s.token = token;
s.info = info;
s.compatInfo = compatInfo;
sendMessage(H.CREATE_SERVICE, s);
}
- H中接收消CREATE_SERVICE息后,调用ActivityThread.handleCreateService()
Service service = null;
java.lang.ClassLoader cl = packageInfo.getClassLoader();
service = (Service) cl.loadClass(data.info.name).newInstance(); (1)
Application app = packageInfo.makeApplication(false, mInstrumentation);(2)
service.attach(context, this, data.info.name, data.token, app,ActivityManager.getService());(3)
service.onCreate();(4)
mServices.put(data.token, service); //缓存当前服务
- handleCreateService做了以下事情,具体细节参照上面Activity中的创建过程:
- 使用类加载器加载类Service并创建Service实例
- 使用Instrumentation创建Application实例,并调用onCreate()初始化
- 创建ContextImpl实例,并通过attach与Service建立联系()(详情见Android插件化——Context机制)
- 调用Service的onCreate()初始化Service
- 使用mServices缓存已经启动的Service对象
2.2、 Service的参数处理
-
前面只分析了Service 的启动过程忽略了一些细节,在ActivityServices的realStartServiceLocked()完成启动后,会调用sendServiceArgsLocked(),在sendServiceArgsLocked()中调用IApplication.scheduleServiceArgs()处理参数,程序最终调用ActivityThread的handleServiceArgs(),从方法名称就可以看出这里处理的是服务的请求参数
-
ActivityThread.handleServiceArgs()
Service s = mServices.get(data.token); // 获取启动的服务
try {
int res;
if (!data.taskRemoved) {
res = s.onStartCommand(data.args, data.flags, data.startId); // 执行onStartCommand传入参数信息
} else {
s.onTaskRemoved(data.args);
res = Service.START_TASK_REMOVED_COMPLETE;
}
}
在handleServiceArgs()中首先从缓存mServices中获取启动的服务,然后调用服务的onStartCommand()传入参数,到此服务的启动和传参过程就执行结束了
2.3、 停止服务
服务的停止过程执行流程个路径和启动基本一致,通过ContextImpl、AMS、ApplicationThread最终进入ActivityThread的handleStopService(),handleStopService()中直接冲缓存中获取对应的服务并调用onDestroy()
private void handleStopService(IBinder token) {
Service s = mServices.remove(token); // 获取启动的Service
s.onDestroy();
}
从上面分析Service的启动过程发现,整个过程和执行的类基本和活动的执行一致,都是通过ContextImpl开始执行操作,经过Binder机制与服务端通信,然后执行服务段的代理AMS类,最后利用IApplication类的代理回到客户端的ActivityThread类中,再使用Handler机制切回主线程执行真正的操作任务;
2.4、 绑定服务
绑定服务从调用ContextWrapper.bindService()开始,然后调用ContextImpl的bindServiceCommom()方法
- bindServiceCommon()
IServiceConnection sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags); (1)
int res = ActivityManager.getService().bindService( //(2)调用AMS.bindService()
mMainThread.getApplicationThread(), getActivityToken(), service,
service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, getOpPackageName(), user.getIdentifier());
//getServiceDispatcher()
public final IServiceConnection getServiceDispatcher(ServiceConnection c,
Context context, Handler handler, int flags) {
ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context); //从缓存中获取ArrayMap
if (map != null) {
sd = map.get(c); //缓存获取
}
sd = new ServiceDispatcher(c, context, handler, flags);
if (map == null) {
map = new ArrayMap<>();
mServices.put(context, map); //缓存ArrayMap
}
map.put(c, sd); //以ServiceConnect为Key保存 sd
return sd.getIServiceConnection(); //返回Sd中保存的InnerConnection实例
}
在bindServiceCommon()中调用getServiceDispatcher()获取IServiceConnection对象,首先从缓存mServices中获取换粗的ServicDispatcher实例,如果缓存不存在则创建ServiceDispatcher实例,ServiceDispatcher中会自动创建并保存内部类InnerConnection的实例,InnerConnection其实是IServiceConnection的代理类;
因为绑定服务可能是跨进程的,所以必须使用跨进程的Binder通信,这里采用IServiceConnection接口实现,ServiceDispatcher的作用是保存进程通信Binder的代理类InnerConnection和ServiceConnection的对应关系,从而使消息能跨进程传递
static final class ServiceDispatcher {
private final ServiceDispatcher.InnerConnection mIServiceConnection;
private final ServiceConnection mConnection; // 内部保存ServiceConnection
private static class InnerConnection extends IServiceConnection.Stub { // 实现IServiceConnection的Binder接口
final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;
InnerConnection(LoadedApk.ServiceDispatcher sd) {
mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
}
}
}
bindServiceCommon除获取ServiceDispatcher对象外,还执行一下逻辑:
- 以键值对的形式保存保存ServiceConnection和ServiceDispatcher的实例在缓存mService中,并返回InnerConnection实例;
- 调用AMS.bindService(),bindService()中又调用ActiveServices.bindServiceLocked()实现服务的启动,整个启动过程和上 面一致;
- 在执行服务启动时,如果此时服务已经在运行,则直接回调绑定方法
int bindServiceLocked(){ // ActiveServices.bindServiceLocked()
if (s.app != null && b.intent.received) { //如果服务已经在运行直接发布连接成功
c.conn.connected(s.name, b.intent.binder, false);
if (b.intent.apps.size() == 1 && b.intent.doRebind) { //客户端重新绑定,并要求回调onRebind()
requestServiceBindingLocked(s, b.intent, callerFg, true);
}
} else if (!b.intent.requested) {
requestServiceBindingLocked(s, b.intent, callerFg, false); //客户端第一次绑定
}
}
- 对于与绑定成功的客户端回调 c.conn.connected(),此处回调的就是InnerConnection.connected(),对于客户端是重新绑定的执行requestServiceBindingLocked()方法回调onRebind() ,这里对重新绑定要符合两个因素,当前进程目前是第一个绑定此服务的进程,而且要绑定的服务已经执行过onUnBind()方法,换句话说此服务之前被绑定过又被断开了,目前处于未绑定状态,下面先看看已经启动的服务是是如何回调通知绑定结果的:
public void connected(ComponentName name, IBinder service, boolean dead)throws RemoteException {
LoadedApk.ServiceDispatcher sd = mDispatcher.get();
if (sd != null) {
sd.connected(name, service, dead); //调用ServiceDispatcher。connected()
}
}
public void connected(ComponentName name, IBinder service, boolean dead) {
if (mActivityThread != null) {
mActivityThread.post(new RunConnection(name, service, 0, dead)); //post发送
} else {
doConnected(name, service, dead);//直接调用
}
}
在InnerConnection.connected()方法中调用内部存储的ServiceDispatcher.connected()方法,根据mActivityThread是否为空确定直接执行doConnected()还是post(),post()发送Runnable最终还是调用doConnected()
- RunConnection的run()回调LoadedApk.ServiceDispatcher.doConnected()
public void doConnected(ComponentName name, IBinder service, boolean dead) {
synchronized (this) {
old = mActiveConnections.get(name); //(1)
if (service != null) {
try {
service.linkToDeath(info.deathMonitor, 0); /(2)设置死亡监听,并缓存服务
mActiveConnections.put(name, info);
} catch (RemoteException e) {
mActiveConnections.remove(name);
return;
}
} else {
mActiveConnections.remove(name);
}
if (old != null) {
old.binder.unlinkToDeath(old.deathMonitor, 0); //(3)
}
}
if (old != null) {
mConnection.onServiceDisconnected(name); //(4)
}
if (service != null) {
mConnection.onServiceConnected(name, service); 、、(5)
}
}
在doConnected()中,执行一下逻辑:
- 从已连接的mActiveConnections中获取之前的连接
- 为Service设置死亡监听
- 对老的绑定回掉之前连接的死亡通知,并回掉ServiceConnection断开连接方法
- 对新的连接回掉连接成功onServiceConnected()通知绑定结果
上面的部分是针对绑定时服务已经启动的,此时可以直接回调绑定结果,对于服务第一次绑定或重新绑定时,在服务启动完成之后会调用requestServiceBindingLocked(),requestServiceBindingLocked会调用IApplication接口
- requestServiceBindingLocked
r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
r.app.repProcState);
- 最终调用ApplicationThread的scheduleBindService()
BindServiceData s = new BindServiceData();
s.token = token;
s.intent = intent;
s.rebind = rebind;
sendMessage(H.BIND_SERVICE, s);
- H中接收消息后,调用ActivityThread.handleBindService(),
Service s = mServices.get(data.token); (1)
if (!data.rebind) {
IBinder binder = s.onBind(data.intent); // 第一次绑定时执行回调onBind()
ActivityManager.getService().publishService(
data.token, data.intent, binder);
} else {
s.onRebind(data.intent); // 重新绑定时执行onReBind()
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
}
- handleBindService执行以下操作:
- 根据Service的Token取出Service对象,并根据是否为第一次绑定和重新绑定回调Service的onBind()和onReBind()
- 对第一次绑定的先调用onBinder回去Binder对象,然后调用AMS的publishService(),publishService最终交给ActivityServices.publishServiceLocked()方法
- publishServiceLocked()中遍历connections集合,获取其中的ConnectionRecord对象,在ConnectionRecord对象中保存这每个Service对应的IServiceConnecttion对象,最终调用IServiceConnecttion.Stub的实现类InnerConnection中connected()方法(详情见上面)
for (int conni=r.connections.size()-1; conni>=0; conni--) {
ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
for (int i=0; i<clist.size(); i++) {
ConnectionRecord c = clist.get(i);
try {
c.conn.connected(r.name, service, false); // 回调ServiceConnection.onServiceConnected()
} catch (Exception e) {
}
}
}
}
2.4、 解除绑定
- ContextImpl.unBindService()
@Override
public void unbindService(ServiceConnection conn) {
if (mPackageInfo != null) {
//(2)
IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(getOuterContext(), conn);
try {
ActivityManager.getService().unbindService(sd); //(3)调用AMS方法
}
}
首先从缓存中获取此服务对应的IServiceConnection对象,然后调用AMS方法接触绑定,方法经过上面的流程后最终执行ActivityThread的handleUnbindService(),在handleUnbindService中取出相应的服务,执行Service的onUnbind()
void handleUnbindService(BindServiceData data) {
Service s = mServices.get(data.token); //取出Serice回调onUnbind()
boolean doRebind = s.onUnbind(data.intent); //回调onUnbind()解除绑定
try {
if (doRebind) { //根据返回确定是否重新绑定
ActivityManager.getService().unbindFinished(
data.token, data.intent, doRebind);
} else {
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
}
}
- 死亡代理
在使用绑定服务时,为了获取服务的运行状态和断开通知,一般会为服务设置死亡监听,在服务死亡时会获取通知及时的做相应的处理,这里DeathMonitor在收到死亡信号时执行death()
private final class DeathMonitor implements IBinder.DeathRecipient{
DeathMonitor(ComponentName name, IBinder service) {
mName = name;
mService = service;
}
public void binderDied() {
death(mName, mService); //处理death事假
}
final ComponentName mName;
final IBinder mService;
}
- death():在服务死亡时会调用death(),death中又调用SeriviceDiapatcher.doDeath()处理服务的解绑和回调
public void death(ComponentName name, IBinder service) {
if (mActivityThread != null) {
mActivityThread.post(new RunConnection(name, service, 1, false));
} else {
doDeath(name, service);
}
}
/处理解除绑定服务
public void doDeath(ComponentName name, IBinder service) {
synchronized (this) {
ConnectionInfo old = mActiveConnections.get(name);
mActiveConnections.remove(name);
old.binder.unlinkToDeath(old.deathMonitor, 0); //移除死亡代理
}
mConnection.onServiceDisconnected(name); //回调断开连接
}
3、ContentProvider
- 关于ContentProvider使用和源码启动过程见Android进阶知识树——ContentProvider使用和工作过程详解
4、BroadcastReceiver
4.1 注册广播
registerBroadCast()
和上面的Activity、Service一样,registerBroadCast()最终调用ContextImpl的registerBroadCast(),registerBroadCast()中调用registerReceiverInternal()方法
- registerReceiverInternal()
if (receiver != null) {
if (mPackageInfo != null && context != null) {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
rd = mPackageInfo.getReceiverDispatcher(
receiver, context, scheduler,
mMainThread.getInstrumentation(), true); //获取的是IIntentReceiver实例
} else {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
rd = new LoadedApk.ReceiverDispatcher(
receiver, context, scheduler, null, true).getIIntentReceiver(); //创建IIntentReceiver实例
}
}
final Intent intent = ActivityManager.getService().registerReceiver( //(2)调用AMS注册广播
mMainThread.getApplicationThread(), mBasePackageName, rd, filter,
broadcastPermission, userId, flags);
registerReceiverInternal()中调用getReceiverDispatcher()获取ReceiverDispatcher的实例,ReceiverDispatcher中封装者BroadCastReceiver对象和IIntentReceiver的代理类InnerReceiver(和Service原理一致),然后调用AMS中方法完成注册;
- IIntentReceiver:一个Binder接口,用于进行跨进程的通信,和Service的处理方式相似
LoadedApk.ReceiverDispatcher.InnerReceiver
static final class ReceiverDispatcher {
final static class InnerReceiver extends IIntentReceiver.Stub {
…….
}
}
ActivityManager.getService().registerReceiver()调用的是ActivityManagerService.registerReceiver()
- ActivityManagerService.registerReceiver()
Iterator<String> actions = filter.actionsIterator(); //(1)遍历IntentFilter中的Action
//(2)获取当前注册用户和所有用户
int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
while (actions.hasNext()) {
String action = actions.next(); //获取每个Action
for (int id : userIds) { //遍历UserIds
// (3)取出每个用户所发送过的所有粘性广播
ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
if (stickies != null) {
ArrayList<Intent> intents = stickies.get(action); //取出这个Action的Intent集合
if (intents != null) {
if (stickyIntents == null) {
stickyIntents = new ArrayList<Intent>();
}
stickyIntents.addAll(intents); //将筛选好的粘性广播保存在stickyIntents中
}
}
}
}
}
ArrayList<Intent> allSticky = null;
if (stickyIntents != null) {
final ContentResolver resolver = mContext.getContentResolver();
for (int i = 0, N = stickyIntents.size(); i < N; i++) {
Intent intent = stickyIntents.get(i);
if (filter.match(resolver, intent, true, TAG) >= 0) { //精准匹配广播类型参数
if (allSticky == null) {
allSticky = new ArrayList<Intent>();
}
allSticky.add(intent); //将匹配符合的Intent添加至allSticky中
}
}
}
// 取出allSticky中第一个Intent,准备发送
Intent sticky = allSticky != null ? allSticky.get(0) : null;
上面详细执行过程见注释,主要从已发送粘性广播历史中查找出符合注册Action的所有Intent的,将Intent保存在sticktIntent集合中,然后在精准匹配Intent的类型和数据等,将符合本次注册监听的意图保存在allSticky中,因为粘性广播在注册完成后会立即发送,所以这里在注册时查找保存;
下面继续广播注册过程:
ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());//(1)
if (rl == null) {
rl = new ReceiverList(this, callerApp, callingPid, callingUid,
userId, receiver); //(2)
if (rl.app != null) {
rl.app.receivers.add(rl);
}
}
mRegisteredReceivers.put(receiver.asBinder(), rl); //(3)
BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
permission, callingUid, userId, instantApp, visibleToInstantApps); //(4)
if (rl.containsFilter(filter)) {
} else {
rl.add(bf);
mReceiverResolver.addFilter(bf);
}
实现注册的流程:
- 从AMS的已注册Receiver列表中查找此广播对象,判断是否是注册过的广播
- 对于新注册的广播创建ReceiverList实例保存receiver对象以及程序的身份和进程信息
- 缓存当前的Receiver保存在mRegisteredReceivers中
- 缓存当前的ReceiverList和注册的IntentFilter保存在BroadcastFilter中
- 将BroadcastFilter添加到ReceiverList内部的集合中保存(内部可保存多个)
- 将bf保存到mReceiverResolver中,所以所有注册的广播都会保存在mReceiverResolver集合中
到此已经完成了广播的注册,对于未匹配粘性广播的此处的allSticky应该为null,如果匹配到发动过的粘性广播,要在广播注册完成后执行一次广播发送,这里到此结束,关于广播发送的详细过程见下一节
- 发送广播:AMS.sendBroadCast()
intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); //设置默认不发送给Stop状态的应用
final String action = intent.getAction(); // 取出Action
try { // 校验如果是保护的系统广播则直接return SUCCESS
isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
} catch (RemoteException e) {
return ActivityManager.BROADCAST_SUCCESS;
}
switch (action) { // 优先处理PMS发送的广播
case Intent.ACTION_UID_REMOVED:
case Intent.ACTION_PACKAGE_REMOVED:
case Intent.ACTION_PACKAGE_CHANGED:
广播发送后会执行系列的检查,检查广播的合法性等,其中系统广播会优先发送;广播发送的第一步就是保存粘性广播
- . 处理发送的粘性广播
if (sticky) {
if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
callingPid, callingUid)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException(msg);
}
ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
ArrayList<Intent> list = stickies.get(intent.getAction());
final int stickiesCount = list.size();
int i;
for (i = 0; i < stickiesCount; i++) {
if (intent.filterEquals(list.get(i))) {
list.set(i, new Intent(intent));
break;
}
}
if (i >= stickiesCount) {
list.add(new Intent(intent));
}
}
执行流程:
- 获取当前应用发送的粘性事件的Map集合
- 从Map 集合中获取当前广播Action 的Intent集合
- 遍历此用户已经发送的广播集合,查找属否已经保存,如果系统中已缓存了此粘性Intent则替换
- 系统中没有此粘性Intent则直接添加新的广播
- . 处理广播接接收
int[] users;
if (userId == UserHandle.USER_ALL) {
users = mUserController.getStartedUserArray(); // 所有用户
} else {
users = new int[] {userId}; // 单一用户
}
//
registeredReceivers = mReceiverResolver.queryIntent(intent,
resolvedType, false, userId);
6. 处理并发送广播
final BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
resultCode, resultData, resultExtras, ordered, sticky, false, userId);
final boolean replaced = replacePending && (queue.replaceParallelBroadcastLocked(r) != null);
if (!replaced) {
queue.enqueueParallelBroadcastLocked(r);
queue.scheduleBroadcastsLocked();
}
执行流程:
- 根据发送的广播确定广播的接收用户:所有用户、单一用户
- 从mReceiverResolver中查询所有符合条件的bf集合,每个bf对象就是一个广播接收者
- 创建BroadcastQueue和BroadcastRecord对象保存广播和接收者信息
- 执行queue.scheduleBroadcastsLocked()发送广播
- . scheduleBroadcastsLocked()
public void scheduleBroadcastsLocked() {
mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this)); //发送事件
mBroadcastsScheduled = true;
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case BROADCAST_INTENT_MSG: {
processNextBroadcast(true);
} break;
case BROADCAST_TIMEOUT_MSG: {
synchronized (mService) {
broadcastTimeoutLocked(true);
}
} break;
}
}
//processNextBroadcast
while (mParallelBroadcasts.size() > 0) {
r = mParallelBroadcasts.remove(0); //
final int N = r.receivers.size(); //
for (int i=0; i<N; i++) {
Object target = r.receivers.get(i); // 取出每个bf
//代码最终调用app.thread.shceduleRegisterRecivier
deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i);
}
addBroadcastToHistoryLocked(r);
}
- 发送BROADCAST_INTENT_MSG事件在handleMessage()中调用processNextBroadcast()
- processNextBroadcast()中取出BroadCastRecord,mParallelBroadcasts中保存着无序广播
- 获取符合传入Intent 的bf的集合
- 遍历所有的bf,执行app.thread.shceduleRegisterRecivier
- app.thread.shceduleRegisterReceiver
public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
int resultCode, String dataStr, Bundle extras, boolean ordered,
boolean sticky, int sendingUser, int processState) throws RemoteException {
updateProcessState(processState, false);
receiver.performReceive(intent, resultCode, dataStr, extras, ordered,sticky, sendingUser);
}
- receiver.performReceive()
@Override
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
rd = mDispatcher.get();
if (rd != null) {
rd.performReceive(intent, resultCode, data, extras,
ordered, sticky, sendingUser);
} else {
mgr.finishReceiver(this, resultCode, data, extras, false, intent.getFlags());
}
}
这里执行IIntentReceiver的代理类InnerReceiver中方法,InnerReceiver中首次调用mDispatcher.get()获取内部保存的LoadedApk.ReceiverDispatcher对象,然后调用LoadedApk.ReceiverDispatcher.performReceive()方法
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
final Args args = new Args(intent, resultCode, data, extras, ordered,
sticky, sendingUser);
if (intent == null || !mActivityThread.post(args.getRunnable())) {
if (mRegistered && ordered) {
IActivityManager mgr = ActivityManager.getService();
args.sendFinished(mgr);
}
}
}
public final Runnable getRunnable() {
return () -> {
final BroadcastReceiver receiver = mReceiver; //执行receiver的onReceiver()
receiver.setPendingResult(this);
receiver.onReceive(mContext, intent);
}
}
执行流程:
- 创建Args对象保存发送的Intent信息
- 调用mActivityThread.post(args.getRunnable())发送事件
- 在Runnable.run()方法中获取目标Receiver
- 执行Receiver的onReceive(mContext, intent)实现广播接收
到此四大组件的启动过程介绍完毕了,这些执行流程在开发中至关重要,尤其在插件化开发中只有连接其原理和过程,才能合理的找到插件化的地方!