四大组件的工作过程

Android深入四大组件(一)应用程序启动过程 在此前的文章中,我讲过了Android系统启动流程和Android应用进程启动过程,这一篇顺理成章来学习Android 7.0的应用程序的启动过程。分析应用程序的启动过程其实就是分析根Activity的启动过程。 阅读详情

首语

Android系统中的四大组件是构成Android应用程序的基础。包括Activity、Service、BroadcastReceiver、ContentProvider。Android开发中无时无刻不在使用这四大组件。因此了解它们的工作过程能让我们对四大组件的理解更加深刻,同时对Android系统的认识更加清晰。

Activity启动过程

Activity启动过长由于包含应用程序启动的过长,内容篇幅过长,进行了拆分。Activity启动过程请查看这篇,Activity启动过程。

Service启动过程

启动Service,我们会调用startService方法,这里会调用mBase的startService方法,这里的mBase对象指的是ContextImpl。

源码路径:frameworks\base\core\java\android\content\ContextWrapper.java

Context mBase;
@Override
public @Nullable ComponentName startService(Intent service) {
     return mBase.startService(service);
}

startService方法调用startServiceCommon方法,然后调用ActivityManagerService类的startService方法。

源码路径:frameworks\base\core\java\android\app\ContextImpl.java

@Override
public ComponentName startService(Intent service) {
     warnIfCallingFromSystemProcess();
     return startServiceCommon(service, false, mUser);
}
private ComponentName startServiceCommon(Intent service, boolean requireForeground,
            UserHandle user) {
        try {
            validateServiceIntent(service);
            service.prepareToLeaveProcess(this);
            //AMS的startService方法
            ComponentName cn = ActivityManager.getService().startService(
                    mMainThread.getApplicationThread(), service,
                    service.resolveTypeIfNeeded(getContentResolver()), requireForeground,
                    getOpPackageName(), getAttributionTag(), user.getIdentifier());
            if (cn != null) {
                if (cn.getPackageName().equals("!")) {
                    throw new SecurityException(
                            "Not allowed to start service " + service
                            + " without permission " + cn.getClassName());
                } else if (cn.getPackageName().equals("!!")) {
                    throw new SecurityException(
                            "Unable to start service " + service
                            + ": " + cn.getClassName());
                } else if (cn.getPackageName().equals("?")) {
                    throw ServiceStartNotAllowedException.newInstance(requireForeground,
                            "Not allowed to start service " + service + ": " + cn.getClassName());
                }
            }
            // If we started a foreground service in the same package, remember the stack trace.
            if (cn != null && requireForeground) {
                if (cn.getPackageName().equals(getOpPackageName())) {
                    Service.setStartForegroundServiceStackTrace(cn.getClassName(),
                            new StackTrace("Last startServiceCommon() call for this service was "
                                    + "made here"));
                }
            }
            return cn;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

startService方法中,mServices类型为ActiveServices,ActiveServices是AMS中负责管理Service的类,调用startServiceLocked方法。

源码路径:frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java

final ActiveServices mServices;
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
            String resolvedType, boolean requireForeground, String callingPackage,
            String callingFeatureId, int userId)
            throws TransactionTooLargeException {
        enforceNotIsolatedCaller("startService");
        enforceAllowedToStartOrBindServiceIfSdkSandbox(service);
        synchronized(this) {
            final int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            final long origId = Binder.clearCallingIdentity();
            ComponentName res;
            try {
                res = mServices.startServiceLocked(caller, service,
                        resolvedType, callingPid, callingUid,
                        requireForeground, callingPackage, callingFeatureId, userId);
            } finally {
                Binder.restoreCallingIdentity(origId);
            }
            return res;
        }
}

startServiceLocked方法重载,retrieveServiceLocked方法会查找是否由于参数service对应的ServiceRecord,如果没找到,就会调用PackageManagerService去获取参数service对应的Service信息,并封装到ServiceRecord,最后将ServiceLookupResult返回。ServiceRecord用于描述一个Service,和之前的ActivityRecord类似。获取到ServiceRecord后,传入到startServiceInnerLocked方法中,然后又调用bringUpServiceLocked方法,获取进程名processName,然后将processName和Service的uid传入getProcessRecordLocked方法中,查询是否存在一个与Service对应的ProcessRecord类型的app,ProcessRecord主要描述运行Service的应用程序进程信息,如果Service对应的app为空,则调用ActivityManagerService类的startProcessLocked方法来创建应用程序进程。这里和前面应用程序启动创建应用程序进程实现一致。如果Service对应的app不为空,则通过realStartServiceLocked方法启动Service,realStartServiceLocked方法中调用thread的scheduleCreateService方法,这里的thread是前面传递的ApplicationThread,ApplicationThread是ActivityThread的内部类。

源码路径:frameworks\base\services\core\java\com\android\server\am\ActiveServices.java

ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
            int callingPid, int callingUid, boolean fgRequired, String callingPackage,
            @Nullable String callingFeatureId, final int userId)
            throws TransactionTooLargeException {
        return startServiceLocked(caller, service, resolvedType, callingPid, callingUid, fgRequired,
                callingPackage, callingFeatureId, userId, false, null);
    }
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
            int callingPid, int callingUid, boolean fgRequired,
            String callingPackage, @Nullable String callingFeatureId, final int userId,
            boolean allowBackgroundActivityStarts, @Nullable IBinder backgroundActivityStartsToken)
            throws TransactionTooLargeException {
    ...
    ServiceLookupResult res =
            retrieveServiceLocked(service, null, resolvedType, callingPackage,
                    callingPid, callingUid, userId, true, callerFg, false, false);
    ServiceRecord r = res.record;
    ...
    final ComponentName realResult =
                startServiceInnerLocked(r, service, callingUid, callingPid, fgRequired, callerFg,
                allowBackgroundActivityStarts, backgroundActivityStartsToken);
}
private ServiceLookupResult retrieveServiceLocked(Intent service,
            String instanceName, String resolvedType, String callingPackage,
            int callingPid, int callingUid, int userId,
            boolean createIfNeeded, boolean callingFromFg, boolean isBindExternal,
            boolean allowInstant) {
        return retrieveServiceLocked(service, instanceName, false, 0, null, resolvedType,
                callingPackage, callingPid, callingUid, userId, createIfNeeded, callingFromFg,
                isBindExternal, allowInstant);
    
private ServiceLookupResult retrieveServiceLocked(Intent service,
            String instanceName, boolean isSdkSandboxService, int sdkSandboxClientAppUid,
            String sdkSandboxClientAppPackage, String resolvedType,
            String callingPackage, int callingPid, int callingUid, int userId,
            boolean createIfNeeded, boolean callingFromFg, boolean isBindExternal,
            boolean allowInstant) {
    ServiceRecord r = null;
    ...
    //这里创建了ServiceRecord对象
    r = new ServiceRecord(mAm, className, name, definingPackageName,
                            definingUid, filter, sInfo, callingFromFg, res,
                            sdkSandboxProcessName, sdkSandboxClientAppUid,
                            sdkSandboxClientAppPackage);
                    res.setService(r);
    ...
    return new ServiceLookupResult(r, resolution.getAlias());
}    
private ComponentName startServiceInnerLocked(ServiceRecord r, Intent service,
            int callingUid, int callingPid, boolean fgRequired, boolean callerFg,
            boolean allowBackgroundActivityStarts, @Nullable IBinder backgroundActivityStartsToken)
            throws TransactionTooLargeException {
    ...
    ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting,
                callingUid, wasStartRequested);
}
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
            boolean callerFg, boolean addToStarting, int callingUid, boolean wasStartRequested)
            throws TransactionTooLargeException {
    ...
    String error = bringUpServiceLocked(r, service.getFlags(), callerFg,
                false /* whileRestarting */,
                false /* permissionsReviewRequired */,
                false /* packageFrozen */,
                true /* enqueueOomAdj */);
}
final ActivityManagerService mAm;    
private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
            boolean whileRestarting, boolean permissionsReviewRequired, boolean packageFrozen,
            boolean enqueueOomAdj)
            throws TransactionTooLargeException {
    //Service 进程
    final String procName = r.processName;
    if (!isolated) {
            app = mAm.getProcessRecordLocked(procName, r.appInfo.uid);
            if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
                        + " app=" + app);
        	//Service进程存在
            if (app != null) {
                //ApplicationThread
                final IApplicationThread thread = app.getThread();
                final int pid = app.getPid();
                final UidRecord uidRecord = app.getUidRecord();
                if (thread != null) {
                    try {
                        app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode,
                                mAm.mProcessStats);
                        //启动Service
                        realStartServiceLocked(r, app, thread, pid, uidRecord, execInFg,
                                enqueueOomAdj);
                        return null;
                    } catch (TransactionTooLargeException e) {
                        throw e;
                    } catch (RemoteException e) {
                        Slog.w(TAG, "Exception when starting service " + r.shortInstanceName, e);
                    }
                }
            }
   //应用进程不存在
   if (app == null && !permissionsReviewRequired && !packageFrozen) {
       ...
	   //创建应用程序进程
       app = mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                        hostingRecord, ZYGOTE_POLICY_FLAG_EMPTY, false, isolated
       //mPendingServices:要求启动但尚未启动的服务列表
       mPendingServices.add(r);
   }
}
 private void realStartServiceLocked(ServiceRecord r, ProcessRecord app,
            IApplicationThread thread, int pid, UidRecord uidRecord, boolean execInFg,
            boolean enqueueOomAdj) throws RemoteException {
     ...
     thread.scheduleCreateService(r, r.serviceInfo,
                    mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
                    app.mState.getReportedProcState());
 }

我们先分析应用程序进程不存在的情况,前面应用程序启动中我们清楚,进程创建完成后会反射动态调用ActivityThread的main方法,接着会调用AMS的attachApplication方法,然后调用attachApplicationLocked方法,attachApplicationLocked方法中会调用ActiveServices类的attachApplicationLocked方法

源码路径:frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java

final ActiveServices mServices;
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
            int pid, int callingUid, long startSeq) {
   	...
    //调用ActivityService的attachApplicationLocked方法
    if (!badApp) {
            try {
                didSomething |= mServices.attachApplicationLocked(app, processName);
                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
                badApp = true;
            }
}

ActiveServices类的attachApplicationLocked方法中会遍历mPendingServices,然后调用realStartServiceLocked启动Service,这就和上面启动Service接轨了,现在进程存在。

boolean attachApplicationLocked(ProcessRecord proc, String processName)
        throws RemoteException {
    if (mPendingServices.size() > 0) {
            ServiceRecord sr = null;
            try {
                for (int i=0; i<mPendingServices.size(); i++) {
                    sr = mPendingServices.get(i);
                    if (proc != sr.isolationHostProc && (proc.uid != sr.appInfo.uid
                            || !processName.equals(sr.processName))) {
                        continue;
                    }

                    final IApplicationThread thread = proc.getThread();
                    final int pid = proc.getPid();
                    final UidRecord uidRecord = proc.getUidRecord();
                    mPendingServices.remove(i);
                    i--;
                    proc.addPackage(sr.appInfo.packageName, sr.appInfo.longVersionCode,
                            mAm.mProcessStats);
                    realStartServiceLocked(sr, proc, thread, pid, uidRecord, sr.createdFromFg,
}

继续分析进程存在的情况,进入到ActivityThread类中,scheduleCreateService方法中将Service启动参数封装成一个CreateServiceData对象,然后发送了一条CREATE_SERVICE的消息,并将CreateServiceData传递,看下Handler是怎么处理CREATE_SERVICE消息,调用handleCreateService方法,最终在handleCreateService方法中,根据CreateServiceData创建Service实例,通过Service的attach方法初始化Service,然后调用Service的onCreate方法,这样Service就被启动了。

源码路径:frameworks\base\core\java\android\app\ActivityThread.java

private class ApplicationThread extends IApplicationThread.Stub {
    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);
        }
}
class H extends Handler {
	public void handleMessage(Message msg) {
        case CREATE_SERVICE:
                    if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
                        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                                ("serviceCreate: " + String.valueOf(msg.obj)));
                    }
                    handleCreateService((CreateServiceData)msg.obj);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
    }
}
private void handleCreateService(CreateServiceData data) {
    Service service = null;
    //缓存读取Application,不存在创建Application
    Application app = packageInfo.makeApplicationInner(false, mInstrumentation);
    service = packageInfo.getAppFactory()
                    .instantiateService(cl, data.info.name, data.intent);
    //上下文
    ContextImpl context = ContextImpl.getImpl(service
                    .createServiceBaseContext(this, packageInfo));
    context.getResources().addLoaders(
                    app.getResources().getLoaders().toArray(new ResourcesLoader[0]));
    //初始化Service
    service.attach(context, this, data.info.name, data.token, app,
                    ActivityManager.getService());
    service.onCreate();
    mServicesData.put(data.token, data);
    mServices.put(data.token, service);
   	try {
	        ActivityManager.getService().serviceDoneExecuting(
                 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
    ...
}

Service绑定过程

除了通过startService方法来启动Service,还可以通过bindService方法来绑定Service,接下来看下Service的绑定过程。

mBase我们知道类型为ContextImpl对象,bindServiceCommon方法中将ServiceConnection转换为IServiceConnection,实现在LoadedApk中,其中executor为null,handler为主线程也就是ActivityThread中我们经常提到的H类。最终调用AMS的bindServiceInstance方法。

源码路径:frameworks\base\core\java\android\content\ContextWrapper.java

	@Override
    public boolean bindService(Intent service, ServiceConnection conn,
            int flags) {
        return mBase.bindService(service, conn, flags);
    }

    @Override
    public boolean bindService(Intent service, int flags, Executor executor,
            ServiceConnection conn) {
        return mBase.bindService(service, flags, executor, conn);
    }

源码路径:frameworks\base\core\java\android\app\ContextImpl.java

@Override
public boolean bindService(Intent service, ServiceConnection conn, int flags) {
    warnIfCallingFromSystemProcess();
    return bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null,
              getUser());
}
final @NonNull ActivityThread mMainThread;
final @NonNull LoadedApk mPackageInfo;
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
            String instanceName, Handler handler, Executor executor, UserHandle user) {
    ...
    IServiceConnection sd;
    if (mPackageInfo != null) {
        	//executor为null
            if (executor != null) {
                sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), executor, flags);
            } else {
                sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
            }
        }
    int res = ActivityManager.getService().bindServiceInstance(
                    mMainThread.getApplicationThread(), getActivityToken(), service,
                    service.resolveTypeIfNeeded(getContentResolver()),
                    sd, flags, instanceName, getOpPackageName(), user.getIdentifier());
}

AMS中bindServiceInstance方法重载调用ActiveServices类的bindServiceLocked方法。

源码路径:frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java

final ActiveServices mServices;
public int bindServiceInstance(IApplicationThread caller, IBinder token, Intent service,
            String resolvedType, IServiceConnection connection, int flags, String instanceName,
            String callingPackage, int userId) throws TransactionTooLargeException {
        return bindServiceInstance(caller, token, service, resolvedType, connection, flags,
                instanceName, false, 0, null, callingPackage, userId);
    }
private int bindServiceInstance(IApplicationThread caller, IBinder token, Intent service,
            String resolvedType, IServiceConnection connection, int flags, String instanceName,
            boolean isSdkSandboxService, int sdkSandboxClientAppUid,
            String sdkSandboxClientAppPackage, String callingPackage, int userId)
            throws TransactionTooLargeException {
    ...
    synchronized (this) {
                return mServices.bindServiceLocked(caller, token, service, resolvedType, connection,
                        flags, instanceName, isSdkSandboxService, sdkSandboxClientAppUid,
                        sdkSandboxClientAppPackage, callingPackage, userId);
            }
}

在bindServiceLocked方法中,构造出ServiceLookupResult,然后调用ServiceRecord类的retrieveAppBindingLocked方法生成AppBindRecord对象,它记录了绑定当前Service的客户端进程信息。应用程序进程通过Intent绑定Service时,通过AppBindRecord来维护Service与应用程序之间的关联,其内部存储了ServiceRecord、ProcessRecord、绑定Service Intent的IntentBindRecord和绑定通信记录信息的ArraySet<ConnectionRecord> ,创建了一个ConnectionRecord对象,它是用于描述应用程序进程和Service建立的一次通信。

然后调用bringUpServiceLocked方法启动Service,具体启动细节在Service启动过程已经说明,接着判断Service是否在运行并且接收到绑定Service返回的Binder,这样应用程序进程就可以通过Binder来获取要绑定的Service访问接口,c.conn的对象为IServiceConnection,具体实现在ServiceDispatcher.InnerConnection,前面有提到,其中ServiceDispatcher为LoadApk的内部类,后面会分析到。

如果当前应用程序进程是第一个与Service进行绑定并且Service调用过onUnBind方法,则调用requestServiceBindingLocked方法,如果应用程序进程没有发送过绑定Service的请求,也会调用requestServiceBindingLocked方法,区别在于最后一个参数,它表示不是重新绑定,当前我们还没有绑定Service呢,requestServiceBindingLocked方法中,我们没有绑定过Service并且是第一个与Service进行绑定,r.app类型为ProcessRecord对象,getThread方法获取的是IApplicationThread,它的实现在ActivityThread类中,继续分析scheduleBindService方法的实现。

源码路径:frameworks\base\services\core\java\com\android\server\am\ActiveServices.java

int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
            String resolvedType, final IServiceConnection connection, int flags,
            String instanceName, boolean isSdkSandboxService, int sdkSandboxClientAppUid,
            String sdkSandboxClientAppPackage, String callingPackage, final int userId)
            throws TransactionTooLargeException {
    	...
   ServiceLookupResult res = retrieveServiceLocked(service, instanceName,
                isSdkSandboxService, sdkSandboxClientAppUid, sdkSandboxClientAppPackage,
                resolvedType, callingPackage, callingPid, callingUid, userId, true, callerFg,
                isBindExternal, allowInstant);
    ServiceRecord s = res.record;
    AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
    ConnectionRecord c = new ConnectionRecord(b, activity,
                    connection, flags, clientLabel, clientIntent,
                    callerApp.uid, callerApp.processName, callingPackage, res.aliasComponent);
	IBinder binder = connection.asBinder();
    s.addConnection(binder, c);
    b.connections.add(c);
    if (activity != null) {
           activity.addConnection(c);
    }
    //启动Service
    if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
                        permissionsReviewRequired, packageFrozen, true) != null) {
                    mAm.updateOomAdjPendingTargetsLocked(OomAdjuster.OOM_ADJ_REASON_BIND_SERVICE);
                    return 0;
                }
    //Service在运行 && 接收到绑定Service返回的Binder, b.intent.received=false
    if (s.app != null && b.intent.received) {
        final ComponentName clientSideComponentName =
                        res.aliasComponent != null ? res.aliasComponent : s.name;
       try {	
           	  // c.conn->IServiceConnection
              c.conn.connected(clientSideComponentName, b.intent.binder, false);
       //第一个与Service进行绑定并已经调用过onUnBind方法,b.intent.doRebind=false
       if (b.intent.apps.size() == 1 && b.intent.doRebind) {
           requestServiceBindingLocked(s, b.intent, callerFg, true);
       }
    //没有发送过绑定service的请求
   	}else if (!b.intent.requested) {
           requestServiceBindingLocked(s, b.intent, callerFg, false)
       ...
    
}
private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
            boolean execInFg, boolean rebind) throws TransactionTooLargeException {
     //i.requested=false;i.apps.size()=1
     if ((!i.requested || rebind) && i.apps.size() > 0) {
            try {
                bumpServiceExecutingLocked(r, execInFg, "bind",
                        OomAdjuster.OOM_ADJ_REASON_BIND_SERVICE);
                r.app.getThread().scheduleBindService(r, i.intent.getIntent(), rebind,
                        r.app.mState.getReportedProcState());
                if (!rebind) {
                    i.requested = true;
                }
                i.hasBound = true;
                i.doRebind = false;
     ...
     return true;
}        

源码路径:frameworks\base\services\core\java\com\android\server\am\ServiceRecord.java

public AppBindRecord retrieveAppBindingLocked(Intent intent,
            ProcessRecord app) {
        Intent.FilterComparison filter = new Intent.FilterComparison(intent);
        IntentBindRecord i = bindings.get(filter);
        if (i == null) {
            i = new IntentBindRecord(this, filter);
            bindings.put(filter, i);
        }
        AppBindRecord a = i.apps.get(app);
        if (a != null) {
            return a;
        }
        a = new AppBindRecord(this, i, app);
        i.apps.put(app, a);
        return a;
    }

源码路径:frameworks\base\services\core\java\com\android\server\am\AppBindRecord.java

final class AppBindRecord {
    final ServiceRecord service;    // The running service.
    final IntentBindRecord intent;  // The intent we are bound to.
    final ProcessRecord client;     // Who has started/bound the service.

    final ArraySet<ConnectionRecord> connections = new ArraySet<>();
    AppBindRecord(ServiceRecord _service, IntentBindRecord _intent,
            ProcessRecord _client) {
        service = _service;
        intent = _intent;
        client = _client;
    }
}

源码路径:frameworks\base\services\core\java\com\android\server\am\IntentBindRecord.java

final class IntentBindRecord {
    /** The running service. */
    final ServiceRecord service;
    /** The intent that is bound.*/
    final Intent.FilterComparison intent; // 
    /** All apps that have bound to this Intent. */
    final ArrayMap<ProcessRecord, AppBindRecord> apps
            = new ArrayMap<ProcessRecord, AppBindRecord>();
    /** Binder published from service. */
    IBinder binder;
    /** Set when we have initiated a request for this binder. */
    boolean requested;
    /** Set when we have received the requested binder. */
    boolean received;
    /** Set when we still need to tell the service all clients are unbound. */
    boolean hasBound;
    /** Set when the service's onUnbind() has asked to be told about new clients. */
    boolean doRebind;
    
    String stringName;    
    IntentBindRecord(ServiceRecord _service, Intent.FilterComparison _intent) {
        service = _service;
        intent = _intent;
    }
}

源码路径:frameworks\base\services\core\java\com\android\server\am\ProcessRecord.java

IApplicationThread getThread() {
    return mThread;
}

scheduleBindService方法中发送一条BIND_SERVICE消息,处理消息调用handleBindService方法,首先获取要绑定的Service,然后判断是否重新绑定,不是重新绑定则调用Service的onBind生命周期方法,重新绑定则会调用Service的onRebind生命周期方法,完成重新绑定。onBind生命周期方法调用后,又调用了AMS的publishService方法

源码路径:frameworks\base\core\java\android\app\ActivityThread.java

private class ApplicationThread extends IApplicationThread.Stub {
    public final void scheduleBindService(IBinder token, Intent intent,
                boolean rebind, int processState) {
            updateProcessState(processState, false);
            BindServiceData s = new BindServiceData();
            s.token = token;
            s.intent = intent;
            s.rebind = rebind;

            if (DEBUG_SERVICE)
                Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid="
                        + Binder.getCallingUid() + " pid=" + Binder.getCallingPid());
            sendMessage(H.BIND_SERVICE, s);
        }
}
class H extends Handler {
    public void handleMessage(Message msg) {
        case BIND_SERVICE:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
                    handleBindService((BindServiceData)msg.obj);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        case UNBIND_SERVICE:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");
                    handleUnbindService((BindServiceData)msg.obj);
                    schedulePurgeIdler();
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
    }
}
private void handleBindService(BindServiceData data) {
    Service s = mServices.get(data.token);
    if (s != null) {
            try {
                data.intent.setExtrasClassLoader(s.getClassLoader());
                data.intent.prepareToEnterProcess(isProtectedComponent(createData.info),
                        s.getAttributionSource());
                try 
                    //是否重新绑定
                    if (!data.rebind) {
                        IBinder binder = s.onBind(data.intent);
                        ActivityManager.getService().publishService(
                                data.token, data.intent, binder);
                    } else {
                        s.onRebind(data.intent);
                        ActivityManager.getService().serviceDoneExecuting(
                                data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
                    }
    ...
}

publishService方法中调用ActiveServices的publishServiceLocked方法。

源码路径:frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java

final ActiveServices mServices;

public void publishService(IBinder token, Intent intent, IBinder service) {
        // Refuse possible leaked file descriptors
        if (intent != null && intent.hasFileDescriptors() == true) {
            throw new IllegalArgumentException("File descriptors passed in Intent");
        }

        synchronized(this) {
            if (!(token instanceof ServiceRecord)) {
                throw new IllegalArgumentException("Invalid service token");
            }
            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
        }
    }

最终调用到LoadApk类中内部类ServiceDispatcher的connect方法。

源码路径:frameworks\base\services\core\java\com\android\server\am\ActiveServices.java

void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
    if (r != null) {
                Intent.FilterComparison filter
                        = new Intent.FilterComparison(intent);
                IntentBindRecord b = r.bindings.get(filter);
                if (b != null && !b.received) {
                    b.binder = service;
                    b.requested = true;
                    b.received = true;
                    ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections();
                    for (int conni = connections.size() - 1; conni >= 0; conni--) {
                        ArrayList<ConnectionRecord> clist = connections.valueAt(conni);
                        for (int i=0; i<clist.size(); i++) {
                            ConnectionRecord c = clist.get(i);
                            final ComponentName clientSideComponentName =
                                    c.aliasComponent != null ? c.aliasComponent : r.name;
                            try {
                                c.conn.connected(clientSideComponentName, service, false);
                            } 
                        }
                    }
                }

                serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false, false);
}

在前面ContextImpl中将ServiceConnection转换为IServiceConnection时,传递的参数是ActivityThread的handler H对象,也就是现在的mActivityThread,发送了一个消息,在RunConnection的run方法中可以知道,调用doConnecteda方法,最终会回调ServiceConnection的onServiceConnected方法,Service 绑定和连接完成。

源码路径:frameworks\base\core\java\android\app\LoadedApk.java

static final class ServiceDispatcher {
    private final Handler mActivityThread;
    public void connected(ComponentName name, IBinder service, boolean dead) {
            if (mActivityExecutor != null) {
                mActivityExecutor.execute(new RunConnection(name, service, 0, dead));
            } else if (mActivityThread != null) {
                mActivityThread.post(new RunConnection(name, service, 0, dead));
            } else {
                doConnected(name, service, dead);
            }
        }
    private final class RunConnection implements Runnable {
            RunConnection(ComponentName name, IBinder service, int command, boolean dead) {
                mName = name;
                mService = service;
                mCommand = command;
                mDead = dead;
            }

            public void run() {
                if (mCommand == 0) {
                    doConnected(mName, mService, mDead);
                } else if (mCommand == 1) {
                    doDeath(mName, mService);
                }
            }

            final ComponentName mName;
            final IBinder mService;
            final int mCommand;
            final boolean mDead;
        }
    public void doConnected(ComponentName name, IBinder service, boolean dead) {
        ...
        if (old != null) {
                mConnection.onServiceDisconnected(name);
            }
            if (dead) {
                mConnection.onBindingDied(name);
            } else {
                // If there is a new viable service, it is now connected.
                if (service != null) {
                    mConnection.onServiceConnected(name, service);
                } else {
                    // The binding machinery worked, but the remote returned null from onBind().
                    mConnection.onNullBinding(name);
                }
            }
    }
}

广播的注册过程

静态注册

了解广播的静态注册需要了解PackageManagerService,后面会对系统服务拆分分析PackageManagerService时再分析广播的静态注册过程。

动态注册

动态注册广播,需要调用registerReceiver方法,它在ContextWrapper中实现。mBase就不用再说了,它是ContextImpl对象。

@Override
public Intent registerReceiver(@Nullable BroadcastReceiver receiver, IntentFilter filter) {
     return mBase.registerReceiver(receiver, filter);
}

registerReceiver方法重载,最终调用registerReceiverInternal方法,scheduler为null,则获取ActivityThread类的Handler。rd是

IIntentReceiver类型,它是一个Binder接口,用于广播的跨进程通信,它的实现在LoadedApk.ReceiverDispatcher.InnerReceiver中。接着调用AMS的registerReceiverWithFeature方法。

源码路径:frameworks\base\core\java\android\app\ContextImpl.java

final @NonNull ActivityThread mMainThread;
final @NonNull LoadedApk mPackageInfo;
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
    return registerReceiver(receiver, filter, null, null);
}
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
            String broadcastPermission, Handler scheduler) {
   return registerReceiverInternal(receiver, getUserId(),
                filter, broadcastPermission, scheduler, getOuterContext(), 0);
}
private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
            IntentFilter filter, String broadcastPermission,
            Handler scheduler, Context context, int flags) {
    IIntentReceiver rd = null;
        if (receiver != null) {
            if (mPackageInfo != null && context != null) {
                if (scheduler == null) {
                    //ActivityThread.H类
                    scheduler = mMainThread.getHandler();
					//广播跨进程通信                
                	rd = mPackageInfo.getReceiverDispatcher(
                    receiver, context, scheduler,
                    mMainThread.getInstrumentation(), true);
            } else {
                if (scheduler == null) {
                    scheduler = mMainThread.getHandler();
                }
                rd = new LoadedApk.ReceiverDispatcher(
                        receiver, context, scheduler, null, true).getIIntentReceiver();
            }
        }
        try {
            ActivityThread thread = ActivityThread.currentActivityThread();
            Instrumentation instrumentation = thread.getInstrumentation();
            if (instrumentation.isInstrumenting()
                    && ((flags & Context.RECEIVER_NOT_EXPORTED) == 0)) {
                flags = flags | Context.RECEIVER_EXPORTED;
            }
            final Intent intent = ActivityManager.getService().registerReceiverWithFeature(
                    mMainThread.getApplicationThread(), mBasePackageName, getAttributionTag(),
                    AppOpsManager.toReceiverId(receiver), rd, filter, broadcastPermission, userId,
                    flags);
            if (intent != null) {
                intent.setExtrasClassLoader(getClassLoader());
                intent.prepareToEnterProcess(ActivityThread.isProtectedBroadcast(intent),
                        getAttributionSource());
            }
            return intent;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
}

registerReceiverWithFeature方法中通过getRecordForAppLOSP方法获取ProcessRecord对象,它是描述请求AMS注册广播接收者的Activity所在的应用程序进程,然后根据传入的IntentFilter类型filter得到actions列表,根据actions和userIds得到所有粘性广播的intent,然后传入到stickyIntents中,接下来从stickyIntents中找到匹配传入的参数filter的粘性广播的intent,将intent存入allSticky中。

继续向下分析,获取ReceiverList,如果为null则重新创建,它是用来存储广播接收者,接下来创建了BroadcastFilter对象,传入ReceiverList对象,它用来描述注册的广播接收者,它也被存储在ReceiverList中,mReceiverResolver是一个IntentResolver对象,BroadcastFilter被添加到mReceiverResolver中,这样AMS接收到广播就可以从mReceiverResolver中找到对应的广播接收者了,动态注册广播完成。

源码路径:frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java

public Intent registerReceiverWithFeature(IApplicationThread caller, String callerPackage,
            String callerFeatureId, String receiverId, IIntentReceiver receiver,
            IntentFilter filter, String permission, int userId, int flags) 
    ArrayList<Intent> stickyIntents = null;
    ProcessRecord callerApp = null;
    synchronized(this) {
            if (caller != null) {
                callerApp = getRecordForAppLOSP(caller);
                callingUid = callerApp.info.uid;
                callingPid = callerApp.getPid();
            } else {
                callerPackage = null;
                callingUid = Binder.getCallingUid();
                callingPid = Binder.getCallingPid();
            }

            instantApp = isInstantApp(callerApp, callerPackage, callingUid);
            userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
                    ALLOW_FULL_ONLY, "registerReceiver", callerPackage);

            Iterator<String> actions = filter.actionsIterator();
            if (actions == null) {
                ArrayList<String> noAction = new ArrayList<String>(1);
                noAction.add(null);
                actions = noAction.iterator();
            }
            boolean onlyProtectedBroadcasts = true;
            int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
            while (actions.hasNext()) {
                String action = actions.next();
                for (int id : userIds) {
                    ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
                    if (stickies != null) {
                        ArrayList<Intent> intents = stickies.get(action);
                        if (intents != null) {
                            if (stickyIntents == null) {
                                stickyIntents = new ArrayList<Intent>();
                            }
                            stickyIntents.addAll(intents);
                        }
                    }
                }
                if (onlyProtectedBroadcasts) {
                    try {
                        onlyProtectedBroadcasts &=
                                AppGlobals.getPackageManager().isProtectedBroadcast(action);
                    } catch (RemoteException e) {
                        onlyProtectedBroadcasts = false;
                        Slog.w(TAG, "Remote exception", e);
                    }
                }
            }
        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 (instantApp &&
                        (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
                    continue;
                }
                if (filter.match(resolver, intent, true, TAG) >= 0) {
                    if (allSticky == null) {
                        allSticky = new ArrayList<Intent>();
                    }
                    allSticky.add(intent);
                }
            }
        }
        
    synchronized (this) {
            IApplicationThread thread;
            if (callerApp != null && ((thread = callerApp.getThread()) == null
                    || thread.asBinder() != caller.asBinder())) {
                // Original caller already died
                return null;
            }
            ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
            if (rl == null) {
                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
                        userId, receiver);
                if (rl.app != null) {
                    final int totalReceiversForApp = rl.app.mReceivers.numberOfReceivers();
                    if (totalReceiversForApp >= MAX_RECEIVERS_ALLOWED_PER_APP) {
                        throw new IllegalStateException("Too many receivers, total of "
                                + totalReceiversForApp + ", registered for pid: "
                                + rl.pid + ", callerPackage: " + callerPackage);
                    }
                    rl.app.mReceivers.addReceiver(rl);
                } else {
                    try {
                        receiver.asBinder().linkToDeath(rl, 0);
                    } catch (RemoteException e) {
                        return sticky;
                    }
                    rl.linkedToDeath = true;
                }
                mRegisteredReceivers.put(receiver.asBinder(), rl);
            } 
            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, callerFeatureId,
                    receiverId, permission, callingUid, userId, instantApp, visibleToInstantApps,
                    exported);
            if (rl.containsFilter(filter)) {
                Slog.w(TAG, "Receiver with filter " + filter
                        + " already registered for pid " + rl.pid
                        + ", callerPackage is " + callerPackage);
            } else {
                //存储在ReceiverList
                rl.add(bf);
                if (!bf.debugCheck()) {
                    Slog.w(TAG, "==> For Dynamic broadcast");
                }
                mReceiverResolver.addFilter(getPackageManagerInternal().snapshot(), bf);
            }

            // Enqueue broadcasts for all existing stickies that match
            // this filter.
            if (allSticky != null) {
                ArrayList receivers = new ArrayList();
                receivers.add(bf);

                final int stickyCount = allSticky.size();
                for (int i = 0; i < stickyCount; i++) {
                    Intent intent = allSticky.get(i);
                    BroadcastQueue queue = broadcastQueueForIntent(intent);
                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
                            null, null, -1, -1, false, null, null, null, null, OP_NONE, null,
                            receivers, null, 0, null, null, false, true, true, -1, false, null,
                            false /* only PRE_BOOT_COMPLETED should be exempt, no stickies */);
                    queue.enqueueParallelBroadcastLocked(r);
                    queue.scheduleBroadcastsLocked();
                }
            }
            return sticky;
        }
}
 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
     ...
 }

广播的发送、接收过程

广播分为多种类型,包括标准广播(无序广播)、有序广播、粘性广播(已废弃)等,我们分别进行分析。

标准广播(无序广播)

发送标准广播(无序广播),需要调用sendBroadcast()方法,实现在ContextImpl类中,最终调用AMS的broadcastIntentWithFeature方法。

	@Override
    public void sendBroadcast(Intent intent) {
        warnIfCallingFromSystemProcess();
        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
        try {
            intent.prepareToLeaveProcess(this);
            ActivityManager.getService().broadcastIntentWithFeature(
                    mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType,
                    null, Activity.RESULT_OK, null, null, null, null /*excludedPermissions=*/,
                    null, AppOpsManager.OP_NONE, null, false, false, getUserId());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

首先验证广播是否合法,然后调用broadcastIntentLocked方法,其中有大量的action判断,针对静态注册的广播(开机,网络等待)处理发送。接着将动态注册的广播接收者和静态注册的广播接收者按照优先级高低不同存储在不同的列表中,再将这两个列表合并到receivers中,receivers中包含所有的广播接收者,创建BroadcastRecord对象将receivers传入,调用BroadcastQueue类的scheduleBroadcastsLocked方法。

源码路径:frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java

@Override
public final int broadcastIntentWithFeature(IApplicationThread caller, String callingFeatureId,
            Intent intent, String resolvedType, IIntentReceiver resultTo,
            int resultCode, String resultData, Bundle resultExtras,
            String[] requiredPermissions, String[] excludedPermissions,
            String[] excludedPackages, int appOp, Bundle bOptions,
            boolean serialized, boolean sticky, int userId) {
		enforceNotIsolatedCaller("broadcastIntent");
        synchronized(this) {
            //验证广播是否合法
            intent = verifyBroadcastLocked(intent);

            final ProcessRecord callerApp = getRecordForAppLOSP(caller);
            final int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();

            final long origId = Binder.clearCallingIdentity();
            try {
                return broadcastIntentLocked(callerApp,
                        callerApp != null ? callerApp.info.packageName : null, callingFeatureId,
                        intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
                        requiredPermissions, excludedPermissions, excludedPackages, appOp, bOptions,
                        serialized, sticky, callingPid, callingUid, callingUid, callingPid, userId);
            } finally {
                Binder.restoreCallingIdentity(origId);
            }
        }    
}
final Intent verifyBroadcastLocked(Intent intent) {
        if (intent != null && intent.hasFileDescriptors() == true) {
            throw new IllegalArgumentException("File descriptors passed in Intent");
        }
        int flags = intent.getFlags();
        if (!mProcessesReady) {
            //启动检查时只接受动态注册的广播接收者-FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
            }
            //动态注册的广播接收者-FLAG_RECEIVER_REGISTERED_ONLY
            else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
                        + " before boot completion");
                throw new IllegalStateException("Cannot broadcast before boot completed");
            }
        }
        return intent;
    }
final int broadcastIntentLocked(ProcessRecord callerApp,
            String callerPackage, String callerFeatureId, Intent intent, String resolvedType,
            IIntentReceiver resultTo, int resultCode, String resultData,
            Bundle resultExtras, String[] requiredPermissions, String[] excludedPermissions,
            String[] excludedPackages, int appOp, Bundle bOptions, boolean ordered,
            boolean sticky, int callingPid,
            int callingUid, int realCallingUid, int realCallingPid, int userId) {
        return broadcastIntentLocked(callerApp, callerPackage, callerFeatureId, intent,
                resolvedType, resultTo, resultCode, resultData, resultExtras, requiredPermissions,
                excludedPermissions, excludedPackages, appOp, bOptions, ordered, sticky, callingPid,
                callingUid, realCallingUid, realCallingPid, userId,
                false /* allowBackgroundActivityStarts */,
                null /* tokenNeededForBackgroundActivityStarts */, null /* broadcastAllowList */);
    }
final int broadcastIntentLocked(ProcessRecord callerApp, String callerPackage,
            @Nullable String callerFeatureId, Intent intent, String resolvedType,
            IIntentReceiver resultTo, int resultCode, String resultData,
            Bundle resultExtras, String[] requiredPermissions,
            String[] excludedPermissions, String[] excludedPackages, int appOp, Bundle bOptions,
            boolean ordered, boolean sticky, int callingPid, int callingUid,
            int realCallingUid, int realCallingPid, int userId,
            boolean allowBackgroundActivityStarts,
            @Nullable IBinder backgroundActivityStartsToken,
            @Nullable int[] broadcastAllowList) {
    final String action = intent.getAction();
    ...
   if ((receivers != null && receivers.size() > 0)
                || resultTo != null) {
            BroadcastQueue queue = broadcastQueueForIntent(intent);
            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, callerPackage,
                    callerFeatureId, callingPid, callingUid, callerInstantApp, resolvedType,
                    requiredPermissions, excludedPermissions, excludedPackages, appOp, brOptions,
                    receivers, resultTo, resultCode, resultData, resultExtras,
                    ordered, sticky, false, userId, allowBackgroundActivityStarts,
                    backgroundActivityStartsToken, timeoutExempt);

            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r);

            final BroadcastRecord oldRecord =
                    replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
            if (oldRecord != null) {
                if (oldRecord.resultTo != null) {
                    final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
                    try {
                        oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
                                oldRecord.intent,
                                Activity.RESULT_CANCELED, null, null,
                                false, false, oldRecord.userId, oldRecord.callingUid, callingUid);
                    } catch (RemoteException e) {
                        Slog.w(TAG, "Failure ["
                                + queue.mQueueName + "] sending broadcast result of "
                                + intent, e);
                    }
                }
            } else {
                queue.enqueueOrderedBroadcastLocked(r);
                queue.scheduleBroadcastsLocked();
            }
        } else {
            if (intent.getComponent() == null && intent.getPackage() == null
                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
            }
        }
}

scheduleBroadcastsLocked方法中发送了一条BROADCAST_INTENT_MSG消息,看下是如何处理消息的,调用processNextBroadcast方法,在processNextBroadcastLocked方法中,遍历mParallelBroadcasts,它是用来存储标准广播,获取列表中存储的BroadcastRecord对象,将这些对象发送给对应的广播接收者,调用deliverToRegisteredReceiverLocked方法,其中做了检查广播发送者或广播接收者的权限,通过权限检查最终调用performReceiveLocked方法,如果广播接收者所在的应用程序进程存在并且在运行,则调用IApplicationThread的scheduleRegisteredReceiver方法,它的实现在ActivityThread的内部类ApplicationThread中。

源码路径:frameworks\base\services\core\java\com\android\server\am\BroadcastQueue.java

public void scheduleBroadcastsLocked() {
        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Schedule broadcasts ["
                + mQueueName + "]: current="
                + mBroadcastsScheduled);

        if (mBroadcastsScheduled) {
            return;
        }
        mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
        mBroadcastsScheduled = true;
    }
private final class BroadcastHandler extends Handler {
        public BroadcastHandler(Looper looper) {
            super(looper, null, true);
        }
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case BROADCAST_INTENT_MSG: {
                    if (DEBUG_BROADCAST) Slog.v(
                            TAG_BROADCAST, "Received BROADCAST_INTENT_MSG ["
                            + mQueueName + "]");
                    processNextBroadcast(true);
                } break;
                case BROADCAST_TIMEOUT_MSG: {
                    synchronized (mService) {
                        broadcastTimeoutLocked(true);
                    }
                } break;
            }
        }
    }
private void processNextBroadcast(boolean fromMsg) {
        synchronized (mService) {
            processNextBroadcastLocked(fromMsg, false);
        }
    }
final ArrayList<BroadcastRecord> mParallelBroadcasts = new ArrayList<>();
final void processNextBroadcastLocked(boolean fromMsg, boolean skipOomAdj) {
    BroadcastRecord r;
     if (fromMsg) {
         	//已经处理了BROADCAST_INTENT_MSG消息
            mBroadcastsScheduled = false;
        }
     while (mParallelBroadcasts.size() > 0) {
         	//获取标准广播
            r = mParallelBroadcasts.remove(0);
            r.dispatchTime = SystemClock.uptimeMillis();
            r.dispatchRealTime = SystemClock.elapsedRealtime();
            r.dispatchClockTime = System.currentTimeMillis();

            if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
                Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                    createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_PENDING),
                    System.identityHashCode(r));
                Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                    createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_DELIVERED),
                    System.identityHashCode(r));
            }

            final int N = r.receivers.size();
            if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Processing parallel broadcast ["
                    + mQueueName + "] " + r);
            for (int i=0; i<N; i++) {
                Object target = r.receivers.get(i);
                //发送给对应的广播接收者
                deliverToRegisteredReceiverLocked(r,
                        (BroadcastFilter) target, false, i);
            }
         ...
        }

}
private void deliverToRegisteredReceiverLocked(BroadcastRecord r,
            BroadcastFilter filter, boolean ordered, int index) {
    ...
    if (filter.receiverList.app != null && filter.receiverList.app.isInFullBackup()) {
                // Skip delivery if full backup in progress
                // If it's an ordered broadcast, we need to continue to the next receiver.
                if (ordered) {
                    skipReceiverLocked(r);
                }
    } else {
                r.receiverTime = SystemClock.uptimeMillis();
                maybeAddAllowBackgroundActivityStartsToken(filter.receiverList.app, r);
                maybeScheduleTempAllowlistLocked(filter.owningUid, r, r.options);
                maybeReportBroadcastDispatchedEventLocked(r, filter.owningUid);
                performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
                        new Intent(r.intent), r.resultCode, r.resultData,
                        r.resultExtras, r.ordered, r.initialSticky, r.userId,
                        filter.receiverList.uid, r.callingUid);
                // parallel broadcasts are fire-and-forget, not bookended by a call to
                // finishReceiverLocked(), so we manage their activity-start token here
                if (filter.receiverList.app != null
                        && r.allowBackgroundActivityStarts && !r.ordered) {
                    postActivityStartTokenRemoval(filter.receiverList.app, r);
                }
    }
}
void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
            Intent intent, int resultCode, String data, Bundle extras,
            boolean ordered, boolean sticky, int sendingUser,
            int receiverUid, int callingUid) throws RemoteException {
    if (app != null) {
            final IApplicationThread thread = app.getThread();
            if (thread != null) {
                try {
                    thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
                            data, extras, ordered, sticky, sendingUser,
                            app.mState.getReportedProcState());
                ...
                }
            } else {
                // Application has died. Receiver doesn't exist.
                throw new RemoteException("app.thread must not be null");
            }
        } else {
            receiver.performReceive(intent, resultCode, data, extras, ordered,
                    sticky, sendingUser);
        }
}

scheduleRegisteredReceiver方法中调用了IIntentReceiver对象的performReceive方法,前面提到过它的实现在LoadApk类的内部类ReceiverDispatcher.InnerReceiver中。

源码路径:frameworks\base\core\java\android\app\ActivityThread.java

private class ApplicationThread extends IApplicationThread.Stub {
    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);
        }
}

InnerReceiver继承IIntentReceiver.Stub,它是Binder通信的服务器端,IIntentReceiver则是Binder通信的客户端、InnerReceiver在本地的代理,它的实现就是InnerReceiver,performReceiver方法中又调用ReceiverDispatcher类的performReceiver方法,将广播的intent等信息封装成Args对象,然后调用Handler类型的mActivityThread发送一条消息,Handler就是ActivityThread 的Handler H 类,getRunnable中最终调用到BroadcastReceiver的onReceive方法,这样注册的广播接收者就接收到了广播并得到了intent。
这里需要注意的是,通过Handler去发送广播,避免广播耗时阻塞。

源码路径:frameworks\base\core\java\android\app\LoadedApk.java

static final class ReceiverDispatcher {
    final static class InnerReceiver extends IIntentReceiver.Stub {
     		@Override
            public void performReceive(Intent intent, int resultCode, String data,
                    Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
                final LoadedApk.ReceiverDispatcher rd;
                if (intent == null) {
                    Log.wtf(TAG, "Null intent received");
                    rd = null;
                } else {
                    rd = mDispatcher.get();
                }
                if (ActivityThread.DEBUG_BROADCAST) {
                    int seq = intent.getIntExtra("seq", -1);
                    Slog.i(ActivityThread.TAG, "Receiving broadcast " + intent.getAction()
                            + " seq=" + seq + " to " + (rd != null ? rd.mReceiver : null));
                }
                if (rd != null) {
                    rd.performReceive(intent, resultCode, data, extras,
                            ordered, sticky, sendingUser);
                } else {
                    // The activity manager dispatched a broadcast to a registered
                    // receiver in this process, but before it could be delivered the
                    // receiver was unregistered.  Acknowledge the broadcast on its
                    // behalf so that the system's broadcast sequence can continue.
                    if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                            "Finishing broadcast to unregistered receiver");
                    IActivityManager mgr = ActivityManager.getService();
                    try {
                        if (extras != null) {
                            extras.setAllowFds(false);
                        }
                        mgr.finishReceiver(this, resultCode, data, extras, false, intent.getFlags());
                    } catch (RemoteException e) {
                        throw e.rethrowFromSystemServer();
                    }
                }
            }   
    }
    final Handler mActivityThread;
    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) {
                Log.wtf(TAG, "Null intent received");
            } else {
                if (ActivityThread.DEBUG_BROADCAST) {
                    int seq = intent.getIntExtra("seq", -1);
                    Slog.i(ActivityThread.TAG, "Enqueueing broadcast " + intent.getAction()
                            + " seq=" + seq + " to " + mReceiver);
                }
            }
            if (intent == null || !mActivityThread.post(args.getRunnable())) {
                if (mRegistered && ordered) {
                    IActivityManager mgr = ActivityManager.getService();
                    if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                            "Finishing sync broadcast to " + mReceiver);
                    args.sendFinished(mgr);
                }
            }
        }
    final class Args extends BroadcastReceiver.PendingResult {
            private Intent mCurIntent;
            private final boolean mOrdered;
            private boolean mDispatched;
            private boolean mRunCalled;

            public Args(Intent intent, int resultCode, String resultData, Bundle resultExtras,
                    boolean ordered, boolean sticky, int sendingUser) {
                super(resultCode, resultData, resultExtras,
                        mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED, ordered,
                        sticky, mIIntentReceiver.asBinder(), sendingUser, intent.getFlags());
                mCurIntent = intent;
                mOrdered = ordered;
            }

            public final Runnable getRunnable() {
                return () -> {
                    final BroadcastReceiver receiver = mReceiver;
                    final boolean ordered = mOrdered;
                    if (ActivityThread.DEBUG_BROADCAST) {
                        int seq = mCurIntent.getIntExtra("seq", -1);
                    }

                    final IActivityManager mgr = ActivityManager.getService();
                    final Intent intent = mCurIntent;
                    mCurIntent = null;
                    mDispatched = true;
                    mRunCalled = true;
                    if (receiver == null || intent == null || mForgotten) {
                        if (mRegistered && ordered) {
                            sendFinished(mgr);
                        }
                        return;
                    }
                    try {
                        ClassLoader cl = mReceiver.getClass().getClassLoader();
                        intent.setExtrasClassLoader(cl);
                        intent.prepareToEnterProcess(ActivityThread.isProtectedBroadcast(intent),
                                mContext.getAttributionSource());
                        setExtrasClassLoader(cl);
                        receiver.setPendingResult(this);
                        //onReceiver接收广播回调
                        receiver.onReceive(mContext, intent);
                    } catch (Exception e) {
                        if (mRegistered && ordered) {
                            if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                                    "Finishing failed broadcast to " + mReceiver);
                            sendFinished(mgr);
                        }
                    }
                    if (receiver.getPendingResult() != null) {
                        finish();
                    }
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                };
            }
        }
}
有序广播

有序广播发送、接收流程几乎和标准广播相似。发送有序广播,通过sendOrderedBroadcast()方法,context对象是ContextImpl,broadcastIntentWithFeature方法的serialized就是用来判断是否是有序广播的,现在是有序广播,传入true,调用到BroadcastQueue类的processNextBroadcastLocked方法中,mParallelBroadcasts我们知道是保存标准广播的。

@Override
    public void sendOrderedBroadcast(Intent intent, String receiverPermission) {
        warnIfCallingFromSystemProcess();
        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
        String[] receiverPermissions = receiverPermission == null ? null
                : new String[] {receiverPermission};
        try {
            intent.prepareToLeaveProcess(this);
            ActivityManager.getService().broadcastIntentWithFeature(
                    mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType,
                    null, Activity.RESULT_OK, null, null, receiverPermissions,
                    null /*excludedPermissions=*/, null, AppOpsManager.OP_NONE, null, true, false,
                    getUserId());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

BroadcastRecord为null,BroadcastDispatcher类的getNextBroadcastLocked方法获取BroadcastRecord,最终也会调用到deliverToRegisteredReceiverLocked方法,接下来其它的流程和标准广播一致。

源码路径:frameworks\base\services\core\java\com\android\server\am\BroadcastQueue.java

final BroadcastDispatcher mDispatcher;
final void processNextBroadcastLocked(boolean fromMsg, boolean skipOomAdj) {
    BroadcastRecord r;
    do {
        final long now = SystemClock.uptimeMillis();
        r = mDispatcher.getNextBroadcastLocked(now);
        ...
    } while (r == null)
    ...
    final BroadcastOptions brOptions = r.options;
    final Object nextReceiver = r.receivers.get(recIdx);
    if (nextReceiver instanceof BroadcastFilter) {
            BroadcastFilter filter = (BroadcastFilter)nextReceiver;
            if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
                    "Delivering ordered ["
                    + mQueueName + "] to registered "
                    + filter + ": " + r);
            deliverToRegisteredReceiverLocked(r, filter, r.ordered, recIdx);
            if (r.receiver == null || !r.ordered) {
                r.state = BroadcastRecord.IDLE;
                scheduleBroadcastsLocked();
            } else {
                if (filter.receiverList != null) {
                    maybeAddAllowBackgroundActivityStartsToken(filter.receiverList.app, r);
                    // r is guaranteed ordered at this point, so we know finishReceiverLocked()
                    // will get a callback and handle the activity start token lifecycle.
                }
            }
           return;
        }
}

ContentProvider启动过程

使用ContentProvider,需要先调用ContextWrapper类的getContentResolver方法,mBase不用说,它是ConexImpl对象,

@Override
public ContentResolver getContentResolver() {
   return mBase.getContentResolver();
}

getContentResolver方法返回了ApplicationContentResolver类型的mContentResolver,ApplicationContentResolver是ContextImpl类的静态内部类,继承自ContentResolver,说明当我们调用ContentResolver类的insert、query等方法时,就会启动ContentProvider,我们以query方法为例,query方法实现在ContentResolver类中。

源码路径:frameworks\base\core\java\android\app\ContextImpl.java

private final ApplicationContentResolver mContentResolver;
@Override
public ContentResolver getContentResolver() {
   return mContentResolver;
}
private static final class ApplicationContentResolver extends ContentResolver {
    private final ActivityThread mMainThread;
    @Override
    protected IContentProvider acquireUnstableProvider(Context c, String auth) {
        return mMainThread.acquireProvider(c,
               ContentProvider.getAuthorityWithoutUserId(auth),
              resolveUserIdFromAuthority(auth), false);
    }
}

可以看到在ContentResolver类中query有三个重载方法,首先调用acquireUnstableProvider方法返回IContentProvider类型的unstableProvider对象,然后调用unstableProvider的query方法,IContentProvider是ContentProvider的本地代理,具体实现在ContentProvider中。acquireUnstableProvider方法判断uri的scheme是否等于content,接着调用acquireUnstableProvider方法,两个参数的acquireUnstableProvider方法在ApplicationContentResolver类中有重写,调用ActivityThread类的acquireProvider方法。

源码路径:frameworks\base\core\java\android\content\ContentResolver.java

@Override
public final @Nullable Cursor query(final @RequiresPermission.Read @NonNull Uri uri,
        @Nullable String[] projection, @Nullable Bundle queryArgs,
        @Nullable CancellationSignal cancellationSignal) {
    IContentProvider unstableProvider = acquireUnstableProvider(uri);
    ...
    try {
           qCursor = unstableProvider.query(mContext.getAttributionSource(), uri, projection,
                  queryArgs, remoteCancellationSignal);
        
    
}
public static final String SCHEME_CONTENT = "content";    
public final IContentProvider acquireUnstableProvider(Uri uri) {
        if (!SCHEME_CONTENT.equals(uri.getScheme())) {
            return null;
        }
        String auth = uri.getAuthority();
        if (auth != null) {
            return acquireUnstableProvider(mContext, uri.getAuthority());
        }
        return null;
}

acquireProvider方法中首先会调用acquireExistingProvider方法检查mProviderMap中是否有目标ContentProvider存在,如果存在直接返回,不存在则调用AMS的getContentProvider方法,installProvider方法用来安装ContentProvider,并将ContentProvider相关数据存储在mProviderMap中,这样就不用每次调用AMS的getContentProvider方法。

源码路径:frameworks\base\core\java\android\app\ActivityThread.java

public final IContentProvider acquireProvider(
            Context c, String auth, int userId, boolean stable) {
    final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
    if (provider != null) {
         return provider;
    }
    ContentProviderHolder holder = null;
        final ProviderKey key = getGetProviderKey(auth, userId);
        try {
            synchronized (key) {
                holder = ActivityManager.getService().getContentProvider(
                        getApplicationThread(), c.getOpPackageName(), auth, userId, stable);
                if (holder != null && holder.provider == null && !holder.mLocal) {
                    synchronized (key.mLock) {
                        if (key.mHolder != null) {
                            if (DEBUG_PROVIDER) {
                                Slog.i(TAG, "already received provider: " + auth);
                            }
                        } else {
                            key.mLock.wait(ContentResolver.CONTENT_PROVIDER_READY_TIMEOUT_MILLIS);
                        }
                        holder = key.mHolder;
                    }
                    if (holder != null && holder.provider == null) {
                        // probably timed out
                        holder = null;
                    }
                }
            }
          ...
          if (holder == null) {
            if (UserManager.get(c).isUserUnlocked(userId)) {
                Slog.e(TAG, "Failed to find provider info for " + auth);
            } else {
                Slog.w(TAG, "Failed to find provider info for " + auth + " (user not unlocked)");
            }
            return null;
        }
		//安装ContentProvider
        holder = installProvider(c, holder, holder.info,
                true /*noisy*/, holder.noReleaseNeeded, stable);
        return holder.provider;
}
final ArrayMap<ProviderKey, ProviderClientRecord> mProviderMap
        = new ArrayMap<ProviderKey, ProviderClientRecord>();    
public final IContentProvider acquireExistingProvider(
            Context c, String auth, int userId, boolean stable) {
        synchronized (mProviderMap) {
            final ProviderKey key = new ProviderKey(auth, userId);
            final ProviderClientRecord pr = mProviderMap.get(key);
            if (pr == null) {
                return null;
            }
            IContentProvider provider = pr.mProvider;
            IBinder jBinder = provider.asBinder();
            if (!jBinder.isBinderAlive()) {
                handleUnstableProviderDiedLocked(jBinder, true);
                return null;
            }
            ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
            if (prc != null) {
                incProviderRefLocked(prc, stable);
            }
            return provider;
        }
    }

getContentProvider方法又调用ContentProviderHelper类的getContentProvider方法,ContentProviderHelper是AMS用来处理内容提供者的类。

源码路径:frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java

final ContentProviderHelper mCpHelper;
@Override
public final ContentProviderHolder getContentProvider(
            IApplicationThread caller, String callingPackage, String name, int userId,
            boolean stable) {
        traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "getContentProvider: ", name);
        try {
            return mCpHelper.getContentProvider(caller, callingPackage, name, userId, stable);
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        }
}

getContentProvider方法又调用getContentProviderImpl方法,其中代码很多,核心部分如下,首先调用AMS的getProcessRecordLocked方法获取ProcessRecord对象,它包含ContentProvider的应用程序进程信息,如果该应用进程已经启动则会调用IApplicationThread的scheduleInstallProvider方法,IApplicationThread实现在ActivityThread内部类ApplicationThread中,否则会调用AMS的startProcessLocked方法来启动进程,启动应用程序进程之前已经分析,流程一致,这里我们先分析没有应用程序进程的流程,我们知道应用程序进程启动完后会调用ActivityThread类main方法,然后调用attach方法,最后来到AMS的attachApplicationLocked方法,调用IApplicationThread的bindApplication方法。

源码路径:frameworks\base\services\core\java\com\android\server\am\ContentProviderHelper.java

ContentProviderHolder getContentProvider(IApplicationThread caller, String callingPackage,
            String name, int userId, boolean stable) {
    ...
    return getContentProviderImpl(caller, name, null, callingUid, callingPackage,
                null, stable, userId);
}
private final ActivityManagerService mService;
private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
            String name, IBinder token, int callingUid, String callingPackage, String callingTag,
            boolean stable, int userId) {
    ...
    ProcessRecord proc = mService.getProcessRecordLocked(
                                cpi.processName, cpr.appInfo.uid);
    IApplicationThread thread;
    if (proc != null && (thread = proc.getThread()) != null
                                && !proc.isKilled()) {
                            if (ActivityManagerDebugConfig.DEBUG_PROVIDER) {
                                Slog.d(TAG, "Installing in existing process " + proc);
                            }
                            final ProcessProviderRecord pr = proc.mProviders;
                            if (!pr.hasProvider(cpi.name)) {
                                checkTime(startTime, "getContentProviderImpl: scheduling install");
                                pr.installProvider(cpi.name, cpr);
                                try {
                                    thread.scheduleInstallProvider(cpi);
                                } catch (RemoteException e) {
                                }
                            }
     } else {
                     checkTime(startTime, "getContentProviderImpl: before start process");
        		     //启动进程
                     proc = mService.startProcessLocked(
                     cpi.processName, cpr.appInfo, false, 0,
                     new HostingRecord(HostingRecord.HOSTING_TYPE_CONTENT_PROVIDER,
                           new ComponentName(
                                          cpi.applicationInfo.packageName, cpi.name)),
                             Process.ZYGOTE_POLICY_FLAG_EMPTY, false, false);
                     checkTime(startTime, "getContentProviderImpl: after start process");
                     cpr.launchingApp = proc;
                     mLaunchingProviders.add(cpr);
}

创建AppBindData对象,传入相关数据,然后发送BIND_APPLICATION消息,传入AppBindData,处理消息调用handleBindApplication方法,首先创建ContextImpl对象,Instrumentation对象并初始化,接着调用installContentProviders方法来启动ContentProvider,最后callApplicationOnCreate方法意味着ContentProvider所在应用程序已经启动。installContentProviders方法中遍历当前应用程序进程的ProviderInfo列表,调用installProvider方法启动这些ContentProvider,最后调用AMS的publishContentProviders方法将这些ContentProvider存储在AMS的mProviderMap中,看下installProvider方法如何启动ContentProvider,首先创建ContentProvider类型的localProvider对象,然后调用它的attachInfo方法,

源码路径:frameworks\base\core\java\android\app\ActivityThread.java

private class ApplicationThread extends IApplicationThread.Stub {
		@Override
        public final void bindApplication(String processName, ApplicationInfo appInfo,
                String sdkSandboxClientAppVolumeUuid, String sdkSandboxClientAppPackage,
                ProviderInfoList providerList, ComponentName instrumentationName,
                ProfilerInfo profilerInfo, Bundle instrumentationArgs,
                IInstrumentationWatcher instrumentationWatcher,
                IUiAutomationConnection instrumentationUiConnection, int debugMode,
                boolean enableBinderTracking, boolean trackAllocation,
                boolean isRestrictedBackupMode, boolean persistent, Configuration config,
                CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
                String buildSerial, AutofillOptions autofillOptions,
                ContentCaptureOptions contentCaptureOptions, long[] disabledCompatChanges,
                SharedMemory serializedSystemFontMap,
                long startRequestedElapsedTime, long startRequestedUptime) {    
            ...
            AppBindData data = new AppBindData();
            data.processName = processName;
            data.appInfo = appInfo;
            data.sdkSandboxClientAppVolumeUuid = sdkSandboxClientAppVolumeUuid;
            data.sdkSandboxClientAppPackage = sdkSandboxClientAppPackage;
            data.providers = providerList.getList();
            data.instrumentationName = instrumentationName;
            data.instrumentationArgs = instrumentationArgs;
            data.instrumentationWatcher = instrumentationWatcher;
            data.instrumentationUiAutomationConnection = instrumentationUiConnection;
            data.debugMode = debugMode;
            data.enableBinderTracking = enableBinderTracking;
            data.trackAllocation = trackAllocation;
            data.restrictedBackupMode = isRestrictedBackupMode;
            data.persistent = persistent;
            data.config = config;
            data.compatInfo = compatInfo;
            data.initProfilerInfo = profilerInfo;
            data.buildSerial = buildSerial;
            data.autofillOptions = autofillOptions;
            data.contentCaptureOptions = contentCaptureOptions;
            data.disabledCompatChanges = disabledCompatChanges;
            data.mSerializedSystemFontMap = serializedSystemFontMap;
            data.startRequestedElapsedTime = startRequestedElapsedTime;
            data.startRequestedUptime = startRequestedUptime;
            sendMessage(H.BIND_APPLICATION, data);
        }
}
class H extends Handler {
    public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                case BIND_APPLICATION:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
                    AppBindData data = (AppBindData)msg.obj;
                    handleBindApplication(data);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
	}
}
Instrumentation mInstrumentation;    
private void handleBindApplication(AppBindData data) {
    final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
    final InstrumentationInfo ii;
        if (data.instrumentationName != null) {
            ii = prepareInstrumentation(data);
        } else {
            ii = null;
        }
    if (ii != null) {
            initInstrumentation(ii, data, appContext);
        } else {
            mInstrumentation = new Instrumentation();
            mInstrumentation.basicInit(this);
        }
    Application app;
    app = data.info.makeApplicationInner(data.restrictedBackupMode, null);
    if (!data.restrictedBackupMode) {
                if (!ArrayUtils.isEmpty(data.providers)) {
                    installContentProviders(app, data.providers);
                }
            }
    try {
             mInstrumentation.onCreate(data.instrumentationArgs);
        }catch (Exception e) {
                throw new RuntimeException(
                    "Exception thrown in onCreate() of "
                    + data.instrumentationName + ": " + e.toString(), e);
            }
    try {
            mInstrumentation.callApplicationOnCreate(app);
    } catch (Exception e) {
            if (!mInstrumentation.onException(app, e)) {
                    throw new RuntimeException(
                      "Unable to create application " + app.getClass().getName()
                      + ": " + e.toString(), e);
                }
    }
}
private void installContentProviders(
            Context context, List<ProviderInfo> providers) {
    final ArrayList<ContentProviderHolder> results = new ArrayList<>();
    for (ProviderInfo cpi : providers) {
            if (DEBUG_PROVIDER) {
                StringBuilder buf = new StringBuilder(128);
                buf.append("Pub ");
                buf.append(cpi.authority);
                buf.append(": ");
                buf.append(cpi.name);
                Log.i(TAG, buf.toString());
            }
            ContentProviderHolder cph = installProvider(context, null, cpi,
                    false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
            if (cph != null) {
                cph.noReleaseNeeded = true;
                results.add(cph);
            }
        }
    try {
            ActivityManager.getService().publishContentProviders(
                getApplicationThread(), results);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
}   
private ContentProviderHolder installProvider(Context context,
            ContentProviderHolder holder, ProviderInfo info,
            boolean noisy, boolean noReleaseNeeded, boolean stable) {
    ContentProvider localProvider = null;
    ...
    try {
                final java.lang.ClassLoader cl = c.getClassLoader();
                LoadedApk packageInfo = peekPackageInfo(ai.packageName, true);
                if (packageInfo == null) {
                    // System startup case.
                    packageInfo = getSystemContext().mPackageInfo;
                }
                localProvider = packageInfo.getAppFactory()
                        .instantiateProvider(cl, info.name);
                provider = localProvider.getIContentProvider();
                if (provider == null) {
                    Slog.e(TAG, "Failed to instantiate class " +
                          info.name + " from sourceDir " +
                          info.applicationInfo.sourceDir);
                    return null;
                }
                if (DEBUG_PROVIDER) Slog.v(
                    TAG, "Instantiating local provider " + info.name);
                // XXX Need to create the correct context for this provider.
                localProvider.attachInfo(c, info);
}    

attachInfo方法重载最终调用onCreate方法,ContentProvider启动完毕。

源码路径:frameworks\base\core\java\android\content\ContentProvider.java

public void attachInfoForTesting(Context context, ProviderInfo info) {
        attachInfo(context, info, true);
    }
public void attachInfo(Context context, ProviderInfo info) {
        attachInfo(context, info, false);
    }
private void attachInfo(Context context, ProviderInfo info, boolean testing) {
    ...
    ContentProvider.this.onCreate();
}

前面进程存在的情况会调用scheduleInstallProvider方法,和上述流程一致。

总结

本文主要分析了四大组件的工作过程,主要分析它的工作过程,没有详细分析周边代码,只对核心部分进行分析。

  • Activity的启动过程。其中包含了根Activity(应用程序)启动过程和普通Activity的启动过程,进程之间的调用关系,同时补充了消息循环创建过程。
  • Service的工作过程。其中包含Service启动过程和绑定过程。
  • 广播的工作过程。其中包含广播的注册过程,分为静态注册和动态注册流程,然后分析广播的发送和接收过程,分为标准广播(无序广播)和有序广播流程。
  • ContentProvider的启动过程。以ContentResolver的query方法为例分析ContentProvider是如何启动的。

四大组件的工作流程大部分是相通的,熟悉了其中一个组件再去看其它组件会简单很多。

抓包工具(五)2025版 Burp Suite Professional的下载、安装、使用 阅读详情

相关推荐

接上篇,记录一下【Unity 3D对博途PLCSIM的通讯】文章有点长~仔细看,很基础

本文参考链接:西门子PLC丨PROFINET通讯仿真(虚拟通讯)做了一些更详细的优化,本文使用的类库并非原作者使用的类库。 首先,昨天项目已经创建好了,这边也加了一个InputField和一个Button,可以实现简单的读取,ok开始。 放入准备好的通讯类库; 新建一个博途的项目,本次测试使用博途V15,测试环境为虚拟机,Unity运行在本地计算机,建立博途项目流程如下: 新建项目,右键项目-属性-保护-对勾,如图: 不得不说的是,仿真中加密的FB块是无法下载的哦~ 添加CPU...

NS_Speak(IVAV) 8056

Android四大组件的工作过程,原理解析

Android四大组件的工作过程,原理解析

qq_27391737的博客 584

Android四大组件(activity task stack) 启动模式 / Activity

服务: 1)简介 服务也是Android的四大组件之一。被称为是没有界面的activity;它拥有自己的生命周期,可以不随着activity的销毁而销毁。 2)创建方式 需要创建继承自Service类的自定义类,并在配置文件中使用标签完成注册,该类回复写一个同名构造方法和一个onBind()的回调方法。 3)使用方法 a) 开启和停止服务 使用startService()方法开启服务,使用stopService()方法停止服务。 适用于例如开启和关闭游戏背景音乐的场景。 b) 绑定和解绑服务 使用bindS

qq_42015021的博客 3823

别再用图片水印了!5种你可能不知道的文本隐写术实战

本文介绍了5种高效的文本隐写术,帮助创作者在不影响内容可读性的情况下嵌入版权信息。从零宽度字符到同形字替换,再到标点符号变形和行尾空格编码,这些技术为数字内容提供了轻量级版权保护方案,特别适用于社交媒体和电子合同等场景。

k8l9m0n的博客 225

Keil C51开发必看:详解data/xdata/bdata内存分配陷阱与避坑指南

本文深入解析Keil C51开发中的data/xdata/bdata内存分配陷阱,提供针对51芯片的高效避坑指南。通过真实案例揭示Keil编译器的隐藏规则,分享内存优化策略和调试技巧,帮助开发者解决data溢出、xdata访问异常等典型问题,提升嵌入式开发效率。

v6b7n8m9q0的博客 1070

Android进阶 四大组件的工作过程(一):Activity的工作过程

本系列文章主要是来介绍Android中四大组件的工作过程的,参照书籍为Android进阶解密,主要还是会涉及到源码的阅读。。本篇文章,主要就是来介绍Activity的工作工程的,这里以启动根Activity为例,查看Activity是如何通过系统启动的。这里我们将其分为三个部分来分析,在这之前还是需要介绍一些基础的知识。

Tai_Monster的博客 1202

每天10分钟,混剪视频Agent产出50条爆款,单月变现6位数(喂饭级教程)

混剪视频是指将多个视频片段、图片或音频素材进行剪辑组合,创造出新的视频内容。随着Coze上线联动剪映功能,混剪视频制作正在进入自动化时代,为创作者带来巨大便利。高效自动化处理:AI可以自动完成琐碎的剪辑工作,让创作者省下大量时间专注于项目策划和创意。批量素材产出:特别适用于抖音、小红书和视频号等平台上的养生、科普、心理、疗愈等垂直领域,可以自动化批量生产图片和视频素材。引流获客:通过优质内容吸引目标受众知识变现:通过教学传授技术工具变现:将搭建好的工作流作为产品销售。

汤师爷的博客 864

第九章 四大组件的工作过程

SystemServer:是一个系统进程 ServiceManager:是一个BinderPoolActivty继承自ContextThemeWrapper; ContextThemeWrapper继承自ContextWrapper; ContextWrapper继承自Context;Context:是一个抽象类。上下文对象声明了要做哪些事情,但它只是一个空壳,是一个综合的环境,现在还并没有具

wwww_dong的博客 501

金仓数据库KCM认证考试介绍【2025年4月更新】

金仓数据库认证资深专家KCM认证考试介绍

qq709869231的博客 3227

西门子S7-1200与FUNUC机器人MODBUS TCP通信

PLC与机器人通讯

Illusssion的博客 1万+

Android四大组件的工作过程

Android四大组件的工作过程概述Activity的启动过程ServiceService的启动过程Service绑定过程ContentProviderContentProvider的启动过程ContentProvider的query过程BroadcastReceiver广播注册过程广播接收/发送过程 概述 这里只分析一般过程,不涉及具体的源码分析。 Activity的启动过程 很明显,Act...

Nigel_Zhou的博客 504

可疑物品遗留检测系统:基于YOLOv8的智能安防解决方案

数据采集与标注模块:负责收集和标注可疑物品图像数据模型训练模块:基于YOLOv8算法训练检测模型推理检测模块:加载训练好的模型进行实时检测用户界面模块:提供友好的操作界面和可视化结果展示报警模块:当检测到可疑物品时触发报警机制:包含多种暴力场景和可疑物品SUAVe:监控场景下的异常行为与物品数据集:包含多种可疑物品自建数据集:针对特定场景收集的数据背包(backpack)手提箱(suitcase)无人看管的包裹(package)可疑箱子(box)

YOLO 435

9_四大组件的工作过程

四大组件的工作过程 1、四大组件的运行状态 2、Activity的工作过程 3、Service的工作过程 4、

yqlee2000的博客 412

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

《Android开发艺术探索》之理解四大组件的工作过程、服务上(十)

第九章 四大组件的工作过程 四大组件分别是Activity,Service,BroadcastReceiver,ContentProvider。如何使用是最基础的,但我们在本章想谈更多:(1)对四大组件的运行状态和工作方式做一个概括性...

云瀚的自习室 821

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

从源码的角度理解四大组件的工作过程——Android开发艺术探索笔记

系统对四大组件的过程进行了很大程度的封装,日常开发中并不需要了解底层的工作原理,那么研究这些原理的意义在哪里呢? 如果你想在技术上更进一步,那么了解一些系统的工作原理是十分必要的,也是开发人员日后成长为高级工程师所必备的技术能力。 Android作为一个优秀的基于Linux操作系统,其内部一定

SparkYuan 2851

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

开发艺术之旅 | 四大组件的工作过程

开发艺术之旅 | 四大组件的工作过程Activity的工作过程 Activity的工作过程 从最常使用的StartActivity方法开始,流程过程如下: 最后调用到app.thread.scheduleLaunchActivity,而app.thread是一个IApplication类型的IInterface接口,其之后关系图如下: 在这个方法里,向一个Handler发送了一个消息,调用pe...

weixin_41802023的博客 239

九、四大组件的工作过程

四大组件的运行状态Android中的四大组件除了BroadcastReceiver之外,其他三大组件都必须在Manifest里面注册,对于BroadcastReceiver来说,它既可以在Manifest里面注册,也可以通过代码来注册。 在调用方式上面,Activity,Service,BroadcastReceiver需要借助Intent,而ContentProvider则无需借助Intent。

qy的专栏 939

《Android开发艺术探索》之学习笔记(九)四大组件的工作过程

四大组件概述 Activity,是一种展示型组件,用于向用户展示UI。它只有一种运行模式:处于启动状态。 Service,是一种计算型组件,用于在后台执行一系列计算任务。它有两种状态:启动状态和绑定状态。Service是运行在主线程的,因此耗时的任务需要在工作线程去完成。Service处于绑定状态时,它内部同样可以进行后台计算。 BroadCastReceiver,是一种消息行组件,用于在不同的组件

tgzzl的专栏 895

四大组件BroadcastReceiver的工作过程

BroadcastReceiver????????????????????????????????????? ?????????? 1)????? ???Manifest.xml????????PackageManagerService???????? 2)????? ??registerReceiver()?? IntentFilt

yeaper_yeo的博客 606

Android系统四大组件工作过程分析(四)- ContentProvider

声明 前阶段对Android系统的启动过程进行了分析:Android系统启动过程分析;现在想对Android程序猿常用的四大组件,包括 Activity、Service、BroadcastReceiver、ContentProvider它们的运行分别进行下分析,因为在平时编写一些Android应用代码时通常直接调用这些组件的API就能轻易实现一些功能,如果想深入了解它们的工作过程就需要对它们进行具体分析了。 本文使用的代码是LineageOS的cm-14.1,对应Android 7.1.2,可以参考我的另

Android系统工程师--小馬佩德罗 194

Android开发艺术探索——第九章:四大组件的工作过程(上)

本篇幅要讲讲四大组件,这也是我们再熟悉不过的,分别是Activity,Service,BroadcastReceiver,ContentProvider,怎么使用我们这里就不多赘述了,我们本篇主要是讲他们的执行流程和工作原理,也让我们更加的了解他们,所以本章的侧重点在于四大组件的工作过程分析,通过分析他们的工作过程我们可以更好的理解系统...

weixin_34240520的博客 114
上一篇: Activity启动过程
下一篇: SystemUI 解析
八归少年
八归少年 新星创作者: 操作系统技术领域 新星创作者: 操作系统技术领域
博客等级 码龄9年 9011粉丝 63原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

八归少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值