Android进阶知识树——Android四大组件启动过程

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. 注释1处调用IActivityManager代理类,IActivityManager是系统的服务接口,在此处采用Binder通信,ActivityManager.getService() 获取到的是它代理实现类ActivityManagerService,然后调用ActivityManagerService.startActivity()方法启动活动
  2. 在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过程中:

  1. 赋值appClass指向要执行的类android.app.Application
  2. 创建Application 中的ContextImpl对象
  3. 调用mInstrumentation.newApplication()实例化Application,并执行attach()绑定Context
static public Application newApplication(Class<?> clazz, Context context){
        Application app = (Application)clazz.newInstance();
        app.attach(context);
        return app;
    }
  1. 执行Application的onCreate()
  • . 调用Activity的attach()完成Window的创建个初始化
  1. 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中的创建过程:
  1. 使用类加载器加载类Service并创建Service实例
  2. 使用Instrumentation创建Application实例,并调用onCreate()初始化
  3. 创建ContextImpl实例,并通过attach与Service建立联系()(详情见Android插件化——Context机制)
  4. 调用Service的onCreate()初始化Service
  5. 使用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对象外,还执行一下逻辑:

  1. 以键值对的形式保存保存ServiceConnection和ServiceDispatcher的实例在缓存mService中,并返回InnerConnection实例;
  2. 调用AMS.bindService(),bindService()中又调用ActiveServices.bindServiceLocked()实现服务的启动,整个启动过程和上 面一致;
  3. 在执行服务启动时,如果此时服务已经在运行,则直接回调绑定方法
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()

  1. 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()中,执行一下逻辑:

  1. 从已连接的mActiveConnections中获取之前的连接
  2. 为Service设置死亡监听
  3. 对老的绑定回掉之前连接的死亡通知,并回掉ServiceConnection断开连接方法
  4. 对新的连接回掉连接成功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执行以下操作:
  1. 根据Service的Token取出Service对象,并根据是否为第一次绑定和重新绑定回调Service的onBind()和onReBind()
  2. 对第一次绑定的先调用onBinder回去Binder对象,然后调用AMS的publishService(),publishService最终交给ActivityServices.publishServiceLocked()方法
  3. 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;
}
  1. 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);
}

实现注册的流程:

  1. 从AMS的已注册Receiver列表中查找此广播对象,判断是否是注册过的广播
  2. 对于新注册的广播创建ReceiverList实例保存receiver对象以及程序的身份和进程信息
  3. 缓存当前的Receiver保存在mRegisteredReceivers中
  4. 缓存当前的ReceiverList和注册的IntentFilter保存在BroadcastFilter中
  5. 将BroadcastFilter添加到ReceiverList内部的集合中保存(内部可保存多个)
  6. 将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)); 
    }
}

执行流程:

  1. 获取当前应用发送的粘性事件的Map集合
  2. 从Map 集合中获取当前广播Action 的Intent集合
  3. 遍历此用户已经发送的广播集合,查找属否已经保存,如果系统中已缓存了此粘性Intent则替换
  4. 系统中没有此粘性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();
}

执行流程:

  1. 根据发送的广播确定广播的接收用户:所有用户、单一用户
  2. 从mReceiverResolver中查询所有符合条件的bf集合,每个bf对象就是一个广播接收者
  3. 创建BroadcastQueue和BroadcastRecord对象保存广播和接收者信息
  4. 执行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);
}
  1. 发送BROADCAST_INTENT_MSG事件在handleMessage()中调用processNextBroadcast()
  2. processNextBroadcast()中取出BroadCastRecord,mParallelBroadcasts中保存着无序广播
  3. 获取符合传入Intent 的bf的集合
  4. 遍历所有的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);
  }
}

执行流程:

  1. 创建Args对象保存发送的Intent信息
  2. 调用mActivityThread.post(args.getRunnable())发送事件
  3. 在Runnable.run()方法中获取目标Receiver
  4. 执行Receiver的onReceive(mContext, intent)实现广播接收

到此四大组件的启动过程介绍完毕了,这些执行流程在开发中至关重要,尤其在插件化开发中只有连接其原理和过程,才能合理的找到插件化的地方!

你可能感兴趣的:(Android高级进阶之旅,四大组件,Activity,Service,Content,Provider,启动过程)