Android开发艺术探索 - 第9章 四大组件的工作过程

46 篇文章 0 订阅
39 篇文章 0 订阅
1.Activity启动过程 ref

从Activity的startActivity方法开始。startActivity的多个重载方法,最终都会调用startActivityForResult方法。mParent代表的是ActivityGroup,API 13之前用于在一个界面中嵌入多个Activity,之后被Fragment替代,所以这里一般为null。该方法中主要调用了Instrumentation#execStartActivity,其中参数mMainThread.getApplicationThread()得到的是ActivityThread的子类ApplicationThread对象,这两个类在Activity的启动过程中发挥了重要的作用:

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
        @Nullable Bundle options) {
    if (mParent == null) {
        options = transferSpringboardActivityOptions(options);
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, this,
                intent, requestCode, options);
        if (ar != null) {
            mMainThread.sendActivityResult(
                mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                ar.getResultData());
        }

execStartActivity的关键代码,即ActivityManager.getService().startActivity。从API 26开始引入了新的ActicityManager类,替代之前旧的实现ActivityManagerNative,不过最终得到都是一个IActivityManager的单例对象,其具体实现为ActivityManagerService(AMS)。紧随其后的方法checkStartActivityResult,则处理了常见的找不到Intent时抛出异常的情况:

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    ...

    try {
        intent.migrateExtraStreamToClipData();
        intent.prepareToLeaveProcess(who);
        int result = ActivityManager.getService()
            .startActivity(whoThread, who.getBasePackageName(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()),
                    token, target != null ? target.mEmbeddedID : null,
                    requestCode, 0, null, options);
        checkStartActivityResult(result, intent);
public static void checkStartActivityResult(int res, Object intent) {
    if (!ActivityManager.isStartResultFatalError(res)) {
        return;
    }

    switch (res) {
        case ActivityManager.START_INTENT_NOT_RESOLVED:
        case ActivityManager.START_CLASS_NOT_FOUND:
            if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
                throw new ActivityNotFoundException(
                        "Unable to find explicit activity class "
                        + ((Intent)intent).getComponent().toShortString()
                        + "; have you declared this activity in your AndroidManifest.xml?");
            throw new ActivityNotFoundException(
                    "No Activity found to handle " + intent);

然后来到AMS#startActivity方法,最终通过startActivityAsUser方法,调用了ActivityStartController#obtainsStarter得到一个ActivityStarter对象,执行了其execute方法。setMayWait设置了其wait标志位为true:

    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
            boolean validateIncomingUser) {
        enforceNotIsolatedCaller("startActivity");

        userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
                Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");

        // TODO: Switch to user app stacks here.
        return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setMayWait(userId)
                .execute();

转到ActivityStarter#execute方法,调用了startActivityMayWait方法(上面提到wait被置为true),经过一翻流转:ActivityStarter->ActivityStackSupervisor->ActivityStack->ActivityStackSupervisor,最终调用到ActivityStackSupervisor#realStartActivityLocked方法,关键代码如下。与之前不同,API 28开始,通过事务的方式启动Activity:

// Create activity launch transaction.
final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
        r.appToken);
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
        System.identityHashCode(r), r.info,
        // TODO: Have this take the merged configuration instead of separate global
        // and override configs.
        mergedConfiguration.getGlobalConfiguration(),
        mergedConfiguration.getOverrideConfiguration(), r.compat,
        r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
        r.persistentState, results, newIntents, mService.isNextTransitionForward(),
        profilerInfo));
...
// Schedule transaction.
mService.getLifecycleManager().scheduleTransaction(clientTransaction);

ClientLifecycleManager#scheduleTransaction,在创建ClientTransaction的时候,IApplicationThread接口的Binder对象就从Parcel中读取出来,并指向了mClient。这里调用了transaction的schedule方法,实际就是调用了Binder对象的scheduleTransaction方法:

void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    final IApplicationThread client = transaction.getClient();
    transaction.schedule();
    if (!(client instanceof Binder)) {
        // If client is not an instance of Binder - it's a remote call and at this point it is
        // safe to recycle the object. All objects used for local calls will be recycled after
        // the transaction is executed on client in ActivityThread.
        transaction.recycle();
    }
}
// ClientTransaction#schedule
public void schedule() throws RemoteException {
    mClient.scheduleTransaction(this);
}

而这个Binder对象远程Binder实体,即是在最开始startActivityForResult方法中,mMainThread.getApplicationThread()得到的ActivityThread$ApplicationThread实例。其scheduleTransaction方法最终调用到ActivityThread父类的scheduleTransaction方法。旧版本中,没有事务的概念,而是直接调用了该方法:

// ActivityThread$ApplicationThread#scheduleTransaction    
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    ActivityThread.this.scheduleTransaction(transaction);
}

而其scheduleTransaction的实现则非常简单,直接发送了一个Message交由Handler处理:

// ClientTransactionHandler#scheduleTransaction
/** Prepare and schedule transaction for execution. */
void scheduleTransaction(ClientTransaction transaction) {
    transaction.preExecute(this);
    sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}

Handler中执行了mTransactionExecutor.execute(transaction);

case EXECUTE_TRANSACTION:
    final ClientTransaction transaction = (ClientTransaction) msg.obj;
    mTransactionExecutor.execute(transaction);
    if (isSystem()) {
        // Client transactions inside system process are recycled on the client side
        // instead of ClientLifecycleManager to avoid being cleared before this
        // message is handled.
        transaction.recycle();
    }
    // TODO(lifecycler): Recycle locally scheduled transactions.
    break;

在TransactionExecutor的excute中,调用executeCallbacks执行具体的事务ClientTransactionItem:

public void execute(ClientTransaction transaction) {
    final IBinder token = transaction.getActivityToken();
    log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);

    executeCallbacks(transaction);

    executeLifecycleState(transaction);
    mPendingActions.clear();
    log("End resolving transaction");
}

@VisibleForTesting
public void executeCallbacks(ClientTransaction transaction) {
    final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
    if (callbacks == null) {
        // No callbacks to execute, return early.
        return;
    }
    log("Resolving callbacks");

    final IBinder token = transaction.getActivityToken();
    ActivityClientRecord r = mTransactionHandler.getActivityClient(token);

    ...
    final int size = callbacks.size();
    for (int i = 0; i < size; ++i) {
        final ClientTransactionItem item = callbacks.get(i);
        ...

        item.execute(mTransactionHandler, token, mPendingActions);
        item.postExecute(mTransactionHandler, token, mPendingActions);

而这里的ClientTransactionItem的实现类,实际为创建事务时,传入的LaunchActivityItem对象,其execute方法调用了client.handleLaunchActivity(r, pendingActions, null /* customIntent */);,这里的client就是ActivityThread:

@Override
public void execute(ClientTransactionHandler client, IBinder token,
        PendingTransactionActions pendingActions) {
    Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
    ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
            mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
            mPendingResults, mPendingNewIntents, mIsForward,
            mProfilerInfo, client);
    client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
    Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}

在ActivityThread的ActivityThread方法中,最终调用到了performLaunchActivity方法:

@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
        PendingTransactionActions pendingActions, Intent customIntent) {
    ...

    final Activity a = performLaunchActivity(r, customIntent);

进入performLaunchActivity方法,开始创建Activity:

  • 从ActivityClientRecord中获取待启动的Activity的组件信息:
    ActivityInfo aInfo = r.activityInfo;
    if (r.packageInfo == null) {
        r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                Context.CONTEXT_INCLUDE_CODE);
    }
    
    ComponentName component = r.intent.getComponent();
    if (component == null) {
        component = r.intent.resolveActivity(
            mInitialApplication.getPackageManager());
        r.intent.setComponent(component);
    }
    
    if (r.activityInfo.targetActivity != null) {
        component = new ComponentName(r.activityInfo.packageName,
                r.activityInfo.targetActivity);
    }
    
  • 创建ContextImpl,通过Instrumentation#newActivity方法使用ClassLoader创建Activity对象:
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
    java.lang.ClassLoader cl = appContext.getClassLoader();
    activity = mInstrumentation.newActivity(
            cl, component.getClassName(), r.intent);
    StrictMode.incrementExpectedActivityCount(activity.getClass());
    r.intent.setExtrasClassLoader(cl);
    r.intent.prepareToEnterProcess();
    if (r.state != null) {
        r.state.setClassLoader(cl);
    }
  • 通过LoadedApk#makeApplication方法尝试创建Application对象。如果Application已经创建过了,则不会再次创建,所以一个应用只有一个Application。而创建过程同Activity也是通过Instrumentation#newApplication方法使用ClassLoader创建,创建完成后,通过callApplicationOnCreate回调Application#onCreate方法:
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        if (mApplication != null) {
            return mApplication;
        }

        try {
            java.lang.ClassLoader cl = getClassLoader();
            if (!mPackageName.equals("android")) {
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                        "initializeJavaContextClassLoader");
                initializeJavaContextClassLoader();
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            }
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            app = mActivityThread.mInstrumentation.newApplication(
                cl, appClass, appContext);
            ...

        if (instrumentation != null) {
            try {
                instrumentation.callApplicationOnCreate(app);
  • 通过Activity#attach方法来完成重要数据的初始化,与ContextImpl的关联,以及Window创建和与Window的关联。
appContext.setOuterContext(activity);
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);
  • 调用Activity#onCreate方法
    通过mInstrumentation.callActivityOnCreate(activity, r.state);回调Activity#onCreate。至此,Activity创建完毕。
2.Service
  1. 启动过程
    Activity#startService->ContextWrapper#startService,这里的mBase,即是创建Activity时,关联的ContextImpl对象。ContextWrapper的实现大部分由ContextImpl完成,典型的桥接模式:
@Override
public ComponentName startService(Intent service) {
    return mBase.startService(service);
}

ContextImpl#startService->startServiceCommon,同Activity,同样会通过AMS去执行startService操作:
```
@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);
        ComponentName cn = ActivityManager.getService().startService(
            mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
                        getContentResolver()), requireForeground,
                        getOpPackageName(), user.getIdentifier());
```

AMS#startService中调用mService的startServiceLocked方法,这个mService的类型是ActiveService,他的作用是辅助AMS进行service的启动/绑定/停止:

@Override
public ComponentName startService(IApplicationThread caller, Intent service,
        String resolvedType, boolean requireForeground, String callingPackage, int userId)
        throws TransactionTooLargeException {
        ...
        try {
            res = mServices.startServiceLocked(caller, service,
                    resolvedType, callingPid, callingUid,
                    requireForeground, callingPackage, userId);

startServiceLocked->startServiceInnerLocked,传递的ServiceRecord描述了一个service记录,其一直贯穿整个service的启动过程。然后调用bringUpServiceLocked:

ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
        boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
    ServiceState stracker = r.getTracker();
    if (stracker != null) {
        stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
    }
    r.callStart = false;
    synchronized (r.stats.getBatteryStats()) {
        r.stats.startRunningLocked();
    }
    String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);

bringUpServiceLocked->realStartServiceLocked,其中主要关注两个调用:首先同Activity,远程调用了ApplicationThread#scheduleCreateService创建service,回调onCreate方法;然后通过sendServiceArgsLocked方法来调用其他方法,如onStartCommand方法:

private final void realStartServiceLocked(ServiceRecord r,
        ProcessRecord app, boolean execInFg) throws RemoteException {
        ...

    try {
        ...
        app.thread.scheduleCreateService(r, r.serviceInfo,
                mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                app.repProcState);
    ...

    sendServiceArgsLocked(r, execInFg, true);

ApplicationThread#scheduleCreateService,同Activity,也是发送Message给Handler处理:

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);
}

Handler异步回调handleCreateService创建service:

  • 通过ClassLoader创建service:
    LoadedApk packageInfo = getPackageInfoNoCheck(
            data.info.applicationInfo, data.compatInfo);
    Service service = null;
    try {
        java.lang.ClassLoader cl = packageInfo.getClassLoader();
        service = packageInfo.getAppFactory()
                .instantiateService(cl, data.info.name, data.intent);
    } catch (Exception e) {
        if (!mInstrumentation.onException(service, e)) {
            throw new RuntimeException(
                "Unable to instantiate service " + data.info.name
                + ": " + e.toString(), e);
        }
    }
    
  • 创建ContextImpl,并通过service的attach方法进行关联;视情况创建Application实例,同Activity;回调service的onCreate方法;最后,将service实例存储到ArrayMap中:
    ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
    context.setOuterContext(service);
    
    Application app = packageInfo.makeApplication(false, mInstrumentation);
    service.attach(context, this, data.info.name, data.token, app,
            ActivityManager.getService());
    service.onCreate();
    mServices.put(data.token, service);
    
    final ArrayMap<IBinder, Service> mServices = new ArrayMap<>();
    

service创建完毕,之后会被远程调用handleServiceArgs方法,进而回调onStartCommand。
2. 绑定过程
Activity#bindService->ContextWrapper#bindService->ContextWrapper#bindServiceCommon,首先,通过LoadedApk#getServiceDispatcher方法,根据ServiceConnection得到IServiceConnection接口的Binder对象,因为bind操作可能是跨进程,所以要使用Binder支持IPC。然后调用AMS的远程bindService方法:

private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler handler, UserHandle user) {
    // Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser.
    IServiceConnection sd;
    ...
    if (mPackageInfo != null) {
        sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
    ...
    try {
    ...
        int res = ActivityManager.getService().bindService(
            mMainThread.getApplicationThread(), getActivityToken(), service,
            service.resolveTypeIfNeeded(getContentResolver()),
            sd, flags, getOpPackageName(), user.getIdentifier());

获得IServiceConnection接口Binder对象的过程:每个Context对应一个map,存储了<ServiceConnection,LoadedApk.ServiceDispatcher>的map,通过这个ServiceDispatcher的getIServiceConnection方法,可以得到其内部类InnerConnection的实例,该类实现了IServiceConnection接口:

public final IServiceConnection getServiceDispatcher(ServiceConnection c,
        Context context, Handler handler, int flags) {
    synchronized (mServices) {
        LoadedApk.ServiceDispatcher sd = null;
        ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
        if (map != null) {
            if (DEBUG) Slog.d(TAG, "Returning existing dispatcher " + sd + " for conn " + c);
            sd = map.get(c);
        }
        if (sd == null) {
            sd = new ServiceDispatcher(c, context, handler, flags);
            if (DEBUG) Slog.d(TAG, "Creating new dispatcher " + sd + " for conn " + c);
            if (map == null) {
                map = new ArrayMap<>();
                mServices.put(context, map);
            }
            map.put(c, sd);
        } else {
            sd.validate(context, handler);
        }
        return sd.getIServiceConnection();
    }
}

AMS#bindService->ActiveServices#bindServiceLocked->bringUpServiceLocked->realStartServiceLocked,之后的流程同创建Service,会通过ApplicationThread来完成service创建以及onCreate方法的回调。另外,realStartServiceLocked方法中,会调用requestServiceBindingsLocked(r, execInFg)方法,根据record执行app.thread.scheduleBindService来进行onBind回调:

private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg)
        throws TransactionTooLargeException {
    for (int i=r.bindings.size()-1; i>=0; i--) {
        IntentBindRecord ibr = r.bindings.valueAt(i);
        if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {
            break;
        }
    }
}
private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
        boolean execInFg, boolean rebind) throws TransactionTooLargeException {
    ...
    if ((!i.requested || rebind) && i.apps.size() > 0) {
        try {
            bumpServiceExecutingLocked(r, execInFg, "bind");
            r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
            r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
                    r.app.repProcState);

在ActivityThread中,同样是通过Handler,最终执行到其handleBindService方法。回调service的onBind方法,onBind返回一个Binder对象,通过AMS#publishService将其传递给client,client的onServiceConnected接收到,bind操作完成:

// ApplicationThread#scheduleBindService
public final void scheduleBindService(IBinder token, Intent intent,
        boolean rebind, int processState) {
    ...
    sendMessage(H.BIND_SERVICE, s);
}
private void handleBindService(BindServiceData data) {
    Service s = mServices.get(data.token);
    if (DEBUG_SERVICE)
        Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
    if (s != null) {
        try {
            data.intent.setExtrasClassLoader(s.getClassLoader());
            data.intent.prepareToEnterProcess();
            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);
                }

client接收Binder的具体过程:AMS#publishService->ActiveServices#publishServiceLocked,其关键代码c.conn.connected(r.name, service, false),c.conn即IServiceConnection接口,对应之前的ServiceDispatcher.InnerConnection类型:

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。这里的mActivityThread的类型为Handler,他是在创建ServiceDispatcher时,传递进来的ActivityThread的Handler实例。所以最终会通过该Handler在主线程执行RunConnection:

        public void connected(ComponentName name, IBinder service, boolean dead) {
            if (mActivityThread != null) {
                mActivityThread.post(new RunConnection(name, service, 0, dead));
            } else {
                doConnected(name, service, dead);
            }
        }

RunConnection#run则执行了ServiceDispatcher#doConnected,client的onServiceConnected被调用:

public void doConnected(ComponentName name, IBinder service, boolean dead) {
    ...
    // If there is a new viable service, it is now connected.
    if (service != null) {
        mConnection.onServiceConnected(name, service);
    } 
3.BroadcastReceiver
  1. 注册过程
    静态注册,同其他三大组件,在应用安装时通过PMS(PackageManagerService)解析并注册。
    动态注册过程如下。
    ContextWrapper#registerReceiver->ContextImpl#registerReceiver->registerReceiverInternal。与bind service类似,也是先得到一个供远程AMS调用的Binder实例,类型为IIntentReceiver,实现类为ReceiverDispatcher.InnerReceiver;之后调用AMS#registerReceiver方法:
private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
        IntentFilter filter, String broadcastPermission,
        Handler scheduler, Context context, int flags) {
    IIntentReceiver rd = null;
    ...
            rd = new LoadedApk.ReceiverDispatcher(
                    receiver, context, scheduler, null, true).getIIntentReceiver();
        }
    }
    try {
        final Intent intent = ActivityManager.getService().registerReceiver(
                mMainThread.getApplicationThread(), mBasePackageName, rd, filter,
                broadcastPermission, userId, flags);

AMS#registerReceiver关键代码,将InnerReceiver远程Binder和IntentFilter对象存储起来:

public Intent registerReceiver(IApplicationThread caller, String callerPackage,
        IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
        int flags) {
        ...
            mRegisteredReceivers.put(receiver.asBinder(), rl);
        ...
        BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
                permission, callingUid, userId, instantApp, visibleToInstantApps);
        if (rl.containsFilter(filter)) {
            Slog.w(TAG, "Receiver with filter " + filter
                    + " already registered for pid " + rl.pid
                    + ", callerPackage is " + callerPackage);
        } else {
            rl.add(bf);
            if (!bf.debugCheck()) {
                Slog.w(TAG, "==> For Dynamic broadcast");
            }
            mReceiverResolver.addFilter(bf);
  1. 发送接收过程
    从广播的发送开始。
    ContextWrapper#sendBroadcast->ContextImpl#sendBroadcast->AMS#broadcastIntent->AMS#broadcastIntentLocked。首先,为其Intent中添加Intent.FLAG_EXCLUDE_STOPPED_PACKAGES,从Android 5.0起,默认不会向已经停止的app发送广播。如果希望向停止的app发送广播,添加Intent.FLAG_INCLUDE_STOPPED_PACKAGES即可,当两个flag同时存在,以include为准:
// By default broadcasts do not go to stopped apps.
intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);

之后,broadcastIntentLocked的主要工作就是,根据intent-filter查找出匹配的receiver,终将满足的receiver添加到BroadcastRecord中,接着执行scheduleBroadcastsLocked方法发送广播:

int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
if (!ordered && NR > 0) {
    ...
    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);
    ...
    if (!replaced) {
        queue.enqueueParallelBroadcastLocked(r);
        queue.scheduleBroadcastsLocked();
    }
    registeredReceivers = null;
    NR = 0;
}
...
if ((receivers != null && receivers.size() > 0)
        || resultTo != null) {
    BroadcastQueue queue = broadcastQueueForIntent(intent);
    BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
            callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
            requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
            resultData, resultExtras, ordered, sticky, false, userId);
    ...
    } else {
        queue.enqueueOrderedBroadcastLocked(r);
        queue.scheduleBroadcastsLocked();
    }

BroadcastQueue#scheduleBroadcastsLocked只是发出一个message:

    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;
    }

之后,Handler调用processNextBroadcast->processNextBroadcastLocked。以无序广播为例,取出BroadcastRecord,遍历其中的receiver,调用deliverToRegisteredReceiverLocked方法向target发出广播:

// First, deliver any non-serialized broadcasts right away.
while (mParallelBroadcasts.size() > 0) {
    r = mParallelBroadcasts.remove(0);
    ...
    for (int i=0; i<N; i++) {
        Object target = r.receivers.get(i);
        if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
                "Delivering non-ordered on [" + mQueueName + "] to registered "
                + target + ": " + r);
        deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i);

deliverToRegisteredReceiverLocked->performReceiveLocked,最终调用了app.thread.scheduleRegisteredReceiver,回到了ApplicationThread:

void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
        Intent intent, int resultCode, String data, Bundle extras,
        boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
    // Send the intent to the receiver asynchronously using one-way binder calls.
    if (app != null) {
        if (app.thread != null) {
            // If we have an app thread, do the call through that so it is
            // correctly ordered with other one-way calls.
            try {
                app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
                        data, extras, ordered, sticky, sendingUser, app.repProcState);

ApplicationThread#scheduleRegisteredReceiver->IIntentReceiver.performReceive,IIntentReceiver即为注册receiver时,创建的Binder对象实例,类型为ReceiverDispatcher.InnerReceiver:

        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#performReceive->ReceiverDispatcher#performReceive,该方法中,通过
创建一个Runnable,将调用onReceive的操作,交给mActivityThread即Handler去执行,该Handler就是ActivityThread中的H:

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())) {

最终,onReceive在主线程中被调用:

try {
    ClassLoader cl = mReceiver.getClass().getClassLoader();
    intent.setExtrasClassLoader(cl);
    intent.prepareToEnterProcess();
    setExtrasClassLoader(cl);
    receiver.setPendingResult(this);
    receiver.onReceive(mContext, intent);
4.ContentProvider


应用启动流程:

  • VM调用ActivityThread的main方法。
  • main方法中,会创建ActivityThread的实例,然后调用其attach方法;同时会创建主线程的消息队列。
  • attch方法中,会调用AMS的远程方法attachApplication,将其ApplicationThread传递给AMS。ApplicationThread是个Binder对象,用于ActivityThread和AMS的通信。
  • 在AMS的attachApplication方法中,会远程调用ApplicationThread的bindApplication方法,ApplicationThread转而交由ActivityThread的Handler处理,具体方法为handleBindApplication。
  • 在handleBindApplication方法中,会创建Application对象,并加载ContentProvider。加载过程发生在回调Application的onCreate方法之前。

ContentProvider可以通过android:multiProcess来为其指定多实例,在每个调用者的进程中,都存在一个CopntentProvider实例。不过大部分的使用场景,ContentProvider为单实例。
访问ContentProvider使用的ContentResolver是个抽象类,getContentResolver得到的实例实际为ContextImpl.ApplicationContentResolver。当通过其四个方法访问ContentProvider时,其所在进程未启动,则会触发其创建,并伴随着ContentProvider的创建。这里以query为例。

ContentResolver#query首先调用了acquireUnstableProvider方法,来获取一个IContentProvider实例。然后调用了子类的acquireUnstableProvider方法,这里的mMainThread即是ActivityThread:

@Override
protected IContentProvider acquireUnstableProvider(Context c, String auth) {
    return mMainThread.acquireProvider(c,
            ContentProvider.getAuthorityWithoutUserId(auth),
            resolveUserIdFromAuthority(auth), false);
}

ActivityThread#acquireProvider,首先会判断目标provider是否存在,如果存在直接返回;如果不存在则通过AMS#getContentProvider方法去创建他,最后通过installProvider修改引用计数:

    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;
        }
        ...
        try {
            synchronized (getGetProviderLock(auth, userId)) {
                holder = ActivityManager.getService().getContentProvider(
                        getApplicationThread(), auth, userId, stable);
        ...
        // Install provider will increment the reference count for us, and break
        // any ties in the race.
        holder = installProvider(c, holder, holder.info,
                true /*noisy*/, holder.noReleaseNeeded, stable);
        return holder.provider;
    }

AMS#getContentProvider->AMS#getContentProviderImpl->startProcessLocked->startProcess,首先创建目标进程。具体为调用了Process.start方法:

private ProcessStartResult startProcess(String hostingType, String entryPoint,
        ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
        String seInfo, String requiredAbi, String instructionSet, String invokeWith,
        long startTime) {
        ...
            startResult = Process.start(entryPoint,
                    app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                    app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                    app.info.dataDir, invokeWith,
                    new String[] {PROC_START_SEQ_IDENT + app.startSeq});

新进程启动后,其入口方法为ActivityThread#main:

    public static void main(String[] args) {
        ...

        ActivityThread thread = new ActivityThread();
        thread.attach(false, startSeq);

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

        // End of event ActivityThreadMain.
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

如前述,Activity#attach->AMS#attachApplication->AMS#attachApplicationImpl->ApplicationThread#bindApplication,然后交由ActivityThread的Handler处理,具体在handleBindApplication方法:
首先,创建ContextImpl和Instrumentation:

final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);

try {
    final ClassLoader cl = instrContext.getClassLoader();
    mInstrumentation = (Instrumentation)
        cl.loadClass(data.instrumentationName.getClassName()).newInstance();
} catch (Exception e) {
    throw new RuntimeException(
        "Unable to instantiate instrumentation "
        + data.instrumentationName + ": " + e.toString(), e);
}

final ComponentName component = new ComponentName(ii.packageName, ii.name);
mInstrumentation.init(this, instrContext, appContext, component,
        data.instrumentationWatcher, data.instrumentationUiAutomationConnection);

创建Application:

Application app;
...
try {
    // If the app is being launched for full backup or restore, bring it up in
    // a restricted environment with the base application class.
    app = data.info.makeApplication(data.restrictedBackupMode, null);
    ...
    mInitialApplication = app;

创建ContentProvider,并调用其onCreate方法。

  • installContentProviders方法中,遍历当前进程的ProviderInfo列表,一一调用其installProvider方法来启动他们。然后将ContentProvider发布到AMS当中,AMS会把其存储在ProviderMap中,下次调用便可直接获得provider实例:
installContentProviders(app, data.providers);
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();
    }
}
  • provider的具体创建过程在installProvider方法中完成。通过ClassLoader创建provider对象,然后调用其attachInfo回调onCreate方法:
    private ContentProviderHolder installProvider(Context context,
            ContentProviderHolder holder, ProviderInfo info,
            boolean noisy, boolean noReleaseNeeded, boolean stable) {
            ...
            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);
                ...
                localProvider.attachInfo(c, info);

provider创建完成,调用Application的onCreate方法:

try {
    mInstrumentation.callApplicationOnCreate(app);

至此,ContentProvider创建完成,其进程的Application也创建完成。使用ContentProvider时,实际上是通过获得的IContentProvider接口去执行远程调用,实际类型为ContentProvider.Transport,其query方法:

@Override
public Cursor query(String callingPkg, Uri uri, @Nullable String[] projection,
        @Nullable Bundle queryArgs, @Nullable ICancellationSignal cancellationSignal) {
    ...
    try {
        return ContentProvider.this.query(
                uri, projection, queryArgs,
                CancellationSignal.fromTransport(cancellationSignal));

调用ContentProvider的query方法,然后通过Binder传递给client,完成了一次调用,其他方法类似。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值