本章讲述Android中的四大组件的工作过程。本章的意义在于加深读者对四大组件的工作方式的认识,由于四大组件的特殊性,我们有必要对它们的工作过程有一定的了解,这也有助于加深对Android整体的体系结构的认识。
四大组件的运行状态
除了 BroadcastReceiver 以外,其他三种组件都必须在 AndroidManifest.xml 中注册。
Activity 负责前台和用户交互。
Service 是一种计算型组件,有 2 种状态:启动状态和绑定状态。 BroadcastReceiver 是一种消息型组件,用于在不同的组件和不同应用之间传递消息。 ContentProvider 是一种数据共享型组件,用于向其他组件乃至其他应用共享数据。Activity 的工作过程
Activity#startActivityForResult
@Override public void startActivityForResult( String who, Intent intent, int requestCode, @Nullable Bundle options) { Uri referrer = onProvideReferrer(); if (referrer != null) { intent.putExtra(Intent.EXTRA_REFERRER, referrer); } options = transferSpringboardActivityOptions(options); // 先由 Instrumentation 执行 execStartActivity Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( this, mMainThread.getApplicationThread(), mToken, who, intent, requestCode, options); // 再由 ActivityThread 执行 sendActivityResult if (ar != null) { mMainThread.sendActivityResult( mToken, who, requestCode, ar.getResultCode(), ar.getResultData()); } cancelInputsAndStartExitTransition(options); }复制代码
mInstrumentation 在 ActivityThread 的 handleBindApplication()
中初始化完成。在启动 Activity 的时候在 attach()
中传给 Activity。
handleBindApplication()
由 ActivityThread$ApplicationThread 的 bindApplication()
调用。
Instrumentation#execStartActivity
public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, String target, Intent intent, int requestCode, Bundle options) { // ... try { // ... // 真正启动 Activity 的是 ActivityManagerNative.getDefault int result = ActivityManagerNative.getDefault() .startActivity(whoThread, who.getBasePackageName(), intent, intent.resolveTypeIfNeeded(who.getContentResolver()), token, target, requestCode, 0, null, options); // 检查 Activity 启动的结果,抛出一些异常 checkStartActivityResult(result, intent); } catch (RemoteException e) { throw new RuntimeException("Failure from system", e); } return null; }复制代码
来看一下 ActivityManagerNative
,
public abstract class ActivityManagerNative extends Binder implements IActivityManager复制代码
ActivityManagerService 继承自 ActivityManagerNative
public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback复制代码
这个方法返回的是 AMS(ActivityManagerService)
/** * Retrieve the system's default/global activity manager. */ static public IActivityManager getDefault() { return gDefault.get(); }复制代码
gDefault 是一个 Singleton 单例对象,第一次创建时调用 create()
创建出 AMS。
private static final SingletongDefault = new Singleton () { protected IActivityManager create() { IBinder b = ServiceManager.getService("activity"); if (false) { Log.v("ActivityManager", "default service binder = " + b); } IActivityManager am = asInterface(b); if (false) { Log.v("ActivityManager", "default service = " + am); } return am; } };复制代码
AMS 和 ActivityStack 互相调用
现在 startActivity 的执行过程走到了 AMS 里面。
AMS 中的 startActivity()
内部的调用逻辑顺序。
startActivity()
startActivityAsUser()
startActivityMayWait()
startActivityLocked()
startActivityUnchecked()
resumeTargetStackIfNeeded()
- ActivityStackSupervisor#
resumeFocusedStackTopActivityLocked()
- ActivityStack#
resumeTopActivityUncheckedLocked()
- ActivityStack#
resumeTopActivityInnerLocked()
- ActivityStackSupervisor#
startSpecificActivityLocked()
- ActivityStackSupervisor#
realStartActivityLocked()
最终会走到 realStartActivityLocked()
com.android.server.am.ActivityStackSupervisor#realStartActivityLocked
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException { // ... // 这里才是真正启动了 Activity 的地方。 // app.thread 是 IApplicationThread app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration), new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo); // ... return true; }复制代码
IApplicationThread 及它的实现者
IApplicationThread 是一个 Binder 类型的接口,内部包含大量启动和停止 Activity 以及 Service 的接口。
不难猜测,IApplicationThread 的实现者完成了大量和 Activity 以及 Service 启动/停止相关的功能。
public interface IApplicationThread extends IInterface复制代码
IApplicationThread 的实现者是 ActivityThread 的内部类 ApplicationThread。
private class ApplicationThread extends ApplicationThreadNative复制代码
public abstract class ApplicationThreadNative extends Binder implements IApplicationThread复制代码
ApplicationThreadNative 的作用其实和系统为 AIDL 文件生成的类是一样的。
ApplicationThreadNative 就是 IApplicationThread 的实现者,由于 ApplicationThreadNative 被系统定义为抽象类,所以 ApplicationThread 就成了 IApplicationThread 最终的实现者。
android.app.ActivityThread$ApplicationThread#scheduleLaunchActivity
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfo info, Configuration curConfig, Configuration overrideConfig, CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state, PersistableBundle persistentState, ListpendingResults, List pendingNewIntents, boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) { // .... sendMessage(H.LAUNCH_ACTIVITY, r); }复制代码
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) { if (DEBUG_MESSAGES) Slog.v( TAG, "SCHEDULE " + what + " " + mH.codeToString(what) + ": " + arg1 + " / " + obj); Message msg = Message.obtain(); msg.what = what; msg.obj = obj; msg.arg1 = arg1; msg.arg2 = arg2; if (async) { msg.setAsynchronous(true); } mH.sendMessage(msg); }复制代码
最终使用 mH 发送一条 msg 通知启动 Activity。
mH 是一个名为 H 的 Handler。
H 处理启动 Activity 的逻辑:
case LAUNCH_ACTIVITY: { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); final ActivityClientRecord r = (ActivityClientRecord) msg.obj; r.packageInfo = getPackageInfoNoCheck( r.activityInfo.applicationInfo, r.compatInfo); handleLaunchActivity(r, null, "LAUNCH_ACTIVITY"); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);}复制代码
启动 Activity 的具体细节
这里又走到了 ActivityThread#handleLaunchActivity()。
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) { // ... // Initialize before creating the activity WindowManagerGlobal.initialize(); // 由 performLaunchActivity 创建出了 Activity 对象 Activity a = performLaunchActivity(r, customIntent); // ... if (a != null) { // ... // 执行 resume 状态 handleResumeActivity(r.token, false, r.isForward, !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason); // 判断 pause if (!r.activity.mFinished && r.startsNotResumed) { performPauseActivityIfNeeded(r, reason); if (r.isPreHoneycomb()) { r.state = oldState; } } } else { try { // finish Activity ActivityManagerNative.getDefault() .finishActivity(r.token, Activity.RESULT_CANCELED, null, Activity.DONT_FINISH_TASK_WITH_ACTIVITY); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } } }复制代码
performLaunchActivity 主要做了 5 件事:
- 从 ActivityClientRecord 中获取待启动的 Activity 的组件信息
- 通过 Instrumentation 的 newActivity 方法使用类加载器创建 Activity 对象
- 通过 LoadedApk 的 makeApplication 方法来尝试创建 Application 对象
- 创建 ContextImpl 对象并通过 Activity 的 attach 方法来完成一些重要数据的初始化
- 调用 Activity 的 onCreate 方法
ActivityThread#performLaunchActivity
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { // 1. 从 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); } // 2. 通过 Instrumentation 的 newActivity 方法使用类加载器创建 Activity 对象 Activity activity = null; try { java.lang.ClassLoader cl = r.packageInfo.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); } } catch (Exception e) { if (!mInstrumentation.onException(activity, e)) { throw new RuntimeException( "Unable to instantiate activity " + component + ": " + e.toString(), e); } } try { //3. 通过LoadedApk的makeApplication方法来尝试创建Application对象 Application app = r.packageInfo.makeApplication(false, mInstrumentation); // ... // 4. 创建ContextImpl对象并通过Activity的attach方法来完成一些重要数据的初始化 if (activity != null) { Context appContext = createBaseContextForActivity(r, activity); CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager()); Configuration config = new Configuration(mCompatConfiguration); // ... // ContextImpl 通过 Activty 的 attach 和 Activity 建立关联 // 在 attach 中 Activity 会完成 Window 的创建并和 Window 关联, // 这样 Window 接收到外部输入事件后就可以将事件传递给 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); // ... // 5. 调用 Activity 的 onCreate 方法, // 此时完成了 Activity 的启动 if (r.isPersistable()) { mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnCreate(activity, r.state); } // ... mActivities.put(r.token, r); // ... return activity; }复制代码
newActivity()
就是通过类加载器创建 Activity 对象
android.app.Instrumentation#newActivity
public Activity newActivity(Class clazz, Context context, IBinder token, Application application, Intent intent, ActivityInfo info, CharSequence title, Activity parent, String id, Object lastNonConfigurationInstance) throws InstantiationException, IllegalAccessException { Activity activity = (Activity)clazz.newInstance(); ActivityThread aThread = null; activity.attach(context, aThread, this, token, 0, application, intent, info, title, parent, id, (Activity.NonConfigurationInstances)lastNonConfigurationInstance, new Configuration(), null, null, null); return activity; }复制代码
android.app.LoadedApk#makeApplication
public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) { if (mApplication != null) { // 一个 app 只能有一个 Application return mApplication; } Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication"); Application app = null; String appClass = mApplicationInfo.className; if (forceDefaultAppClass || (appClass == null)) { appClass = "android.app.Application"; } try { java.lang.ClassLoader cl = getClassLoader(); if (!mPackageName.equals("android")) { initializeJavaContextClassLoader(); } ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this); // 通过 Instrumentation 的 newApplication创建对象。也是用类加载器加载的。 app = mActivityThread.mInstrumentation.newApplication( cl, appClass, appContext); appContext.setOuterContext(app); } catch (Exception e) { // ... } mActivityThread.mAllApplications.add(app); mApplication = app; if (instrumentation != null) { instrumentation.callApplicationOnCreate(app); } // Rewrite the R 'constants' for all library apks. SparseArraypackageIdentifiers = getAssets(mActivityThread) .getAssignedPackageIdentifiers(); final int N = packageIdentifiers.size(); for (int i = 0; i < N; i++) { final int id = packageIdentifiers.keyAt(i); if (id == 0x01 || id == 0x7f) { continue; } rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id); } Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); return app; }复制代码
Service 的工作过程
Service 分为两种工作状态:
- 启动状态,主要用于执行后台计算
- 绑定状态,主要用于其他组件和 Service 的交互
这两种状态可以共存。
Intent intentService = new Intent(this,MyService.class);// 启动startService(intentService);// 绑定bindService(intentService,mServiceConnection,BIND_AUTO_CREATE);复制代码
启动过程
从 ContextWrapper 的 startService 开始。
public ComponentName startService(Intent service) { return mBase.startService(service);}复制代码
Activity 创建的时候会通过 attach()
将一个 ContextImpl 对象关联起来,这个 ContextImpl 对象就是上面的 mBase
。
ContextWrapper 的大部分实现都是由 mBase 实现。这是桥接模式。
ContextImpl 中 startService()
的最终实现时 startServiceCommon()
:
android.app.ContextImpl#startServiceCommon
private ComponentName startServiceCommon(Intent service, UserHandle user) { validateServiceIntent(service); service.prepareToLeaveProcess(this); // 这里通过 AMS 远程调用 startService ComponentName cn = ActivityManagerNative.getDefault().startService( mMainThread.getApplicationThread(), service,service.resolveTypeIfNeeded(getContentResolver()), getOpPackageName(), user.getIdentifier()); // .... return cn; }复制代码
com.android.server.am.ActivityManagerService#startService
@Override public ComponentName startService(IApplicationThread caller, Intent service, String resolvedType, String callingPackage, int userId) throws TransactionTooLargeException { enforceNotIsolatedCaller("startService"); // Refuse possible leaked file descriptors // ... synchronized(this) { final int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); // mServices 是 ActiveService,辅助 AMS 管理 Service. ComponentName res = mServices.startServiceLocked(caller, service, resolvedType, callingPid, callingUid, callingPackage, userId); Binder.restoreCallingIdentity(origId); return res; } }复制代码
在 AMS 的 startService()
内部的调用链。
- ActiveService#
startServiceLocked()
- ActiveService#
startServiceInnerLocked()
- ActiveService#
bringUpServiceLocked()
- ActiveService#
sendServiceArgsLocked()
- ActiveService#
realStartServiceLocked()
com.android.server.am.ActiveService#startServiceInnerLocked
// ServiceRecord 描述的是一个 Service 记录,它贯穿整个 Service 的启动过程。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(); } // 将具体的启动工作交给了 bringUpServiceLocked String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false); if (error != null) { return new ComponentName("!!", error); } if (r.startRequested && addToStarting) { boolean first = smap.mStartingBackground.size() == 0; smap.mStartingBackground.add(r); r.startingBgTimeout = SystemClock.uptimeMillis() + BG_START_TIMEOUT; // ... if (first) { smap.rescheduleDelayedStarts(); } } else if (callerFg) { smap.ensureNotStartingBackground(r); } return r.name; }复制代码
com.android.server.am.ActiveService#realStartServiceLocked
private final void realStartServiceLocked(ServiceRecord r, ProcessRecord app, boolean execInFg) throws RemoteException { // ... r.app = app; r.restartTime = r.lastActivity = SystemClock.uptimeMillis(); final boolean newService = app.services.add(r); bumpServiceExecutingLocked(r, execInFg, "create"); mAm.updateLruProcessLocked(app, false, null); mAm.updateOomAdjLocked(); boolean created = false; try { // ... synchronized (r.stats.getBatteryStats()) { r.stats.startLaunchedLocked(); } mAm.notifyPackageUse(r.serviceInfo.packageName, PackageManager.NOTIFY_PACKAGE_USE_SERVICE); app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE); // 通过 ActivityThread 的 scheduleCreateService 创建 Service 对象 app.thread.scheduleCreateService(r, r.serviceInfo, mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo), app.repProcState); r.postNotification(); created = true; } catch (DeadObjectException e) { // ... } finally { // ... } if (r.whitelistManager) { app.whitelistManager = true; } requestServiceBindingsLocked(r, execInFg); updateServiceClientActivitiesLocked(app, null, true); // If the service is in the started state, and there are no // pending arguments, then fake up one so its onStartCommand() will // be called. if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) { r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), null, null)); } // 调用 Service 的其他方法。比如 onStartCommand. sendServiceArgsLocked(r, execInFg, true); // ... }复制代码
和 Activity 一样通过 Handler 发送 msg。
ActivityThread#scheduleCreateService
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); }复制代码
ActivityThread#handleCreateService
private void handleCreateService(CreateServiceData data) { // If we are getting ready to gc after going to the background, well // we are back active so skip it. unscheduleGcIdler(); LoadedApk packageInfo = getPackageInfoNoCheck( data.info.applicationInfo, data.compatInfo); Service service = null; try { // 通过类加载器创建 Service 的实例 java.lang.ClassLoader cl = packageInfo.getClassLoader(); service = (Service) cl.loadClass(data.info.name).newInstance(); } catch (Exception e) { // ... } try { // 创建 ContextImpl 对象 ContextImpl context = ContextImpl.createAppContext(this, packageInfo); context.setOuterContext(service); // 创建 Application Application app = packageInfo.makeApplication(false, mInstrumentation); // 通过 attach 将 Service 对象和 ContextImpl 对象关联。 service.attach(context, this, data.info.name, data.token, app, ActivityManagerNative.getDefault()); // 调用 service 的 onCreate service.onCreate(); // 将 service 存入集合中 mServices.put(data.token, service); try { ActivityManagerNative.getDefault().serviceDoneExecuting( data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0); } catch (RemoteException e) { } } // ... }复制代码
除此之外 ActivieService#sendServiceArgsLocked()
内部会调用 ActivityThread 的 scheduleServiceArgs()
, 最终调用 handleServiceArgs()
android.app.ActivityThread#handleServiceArgs
private void handleServiceArgs(ServiceArgsData data) { Service s = mServices.get(data.token); if (data.args != null) { data.args.setExtrasClassLoader(s.getClassLoader()); data.args.prepareToEnterProcess(); } int res; if (!data.taskRemoved) { // 调用了 service 的 onStartCommand() res = s.onStartCommand(data.args, data.flags, data.startId); } else { s.onTaskRemoved(data.args); res = Service.START_TASK_REMOVED_COMPLETE; } QueuedWork.waitToFinish(); ActivityManagerNative.getDefault().serviceDoneExecuting( data.token, SERVICE_DONE_EXECUTING_START, data.startId, res); ensureJitEnabled(); }复制代码
Service 的绑定过程
和启动过程一样是从 ContextImpl 中的 bindServiceCommon()
开始。
ContextImpl#bindServiceCommon
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler handler, UserHandle user) { IServiceConnection sd; // 将客户端的 ServiceConnection 对象转成 ServiceDispatcher.InnerConnection。 // 因为服务的绑定有可能是跨进程的,ServiceConnection 对象必须借助于 // Binder 才能让远程服务回调自己的方法。 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags); IBinder token = getActivityToken(); if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null && mPackageInfo.getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) { flags |= BIND_WAIVE_PRIORITY; } service.prepareToLeaveProcess(this); // 调用 AMS 的 bindService int res = ActivityManagerNative.getDefault().bindService( mMainThread.getApplicationThread(), getActivityToken(), service, service.resolveTypeIfNeeded(getContentResolver()), sd, flags, getOpPackageName(), user.getIdentifier()); return res != 0; }复制代码
android.app.LoadedApk#getServiceDispatcher
private final ArrayMap> mServices; public final IServiceConnection getServiceDispatcher(ServiceConnection c, Context context, Handler handler, int flags) { // mService 是一个 map synchronized (mServices) { // 一顿操作,map 有的话从 map 取,没有就创建存进去。 LoadedApk.ServiceDispatcher sd = null; ArrayMap map = mServices.get(context); if (map != null) { sd = map.get(c); } if (sd == null) { sd = new ServiceDispatcher(c, context, handler, flags); if (map == null) { map = new ArrayMap (); mServices.put(context, map); } map.put(c, sd); } else { sd.validate(context, handler); } // 返回内部保寸的 IServiceConnection 对象 return sd.getIServiceConnection(); } }复制代码
ActivityManagerService#bindService
public int bindService(IApplicationThread caller, IBinder token, Intent service, String resolvedType, IServiceConnection connection, int flags, String callingPackage, int userId) throws TransactionTooLargeException { enforceNotIsolatedCaller("bindService"); // ... synchronized(this) { return mServices.bindServiceLocked(caller, token, service, resolvedType, connection, flags, callingPackage, userId); } }复制代码
AMS 的调用过程:
- bindService()
- ActiveServices#bindServiceLocked()
- ActiveServices#bringUpServiceLocked()
- ActiveServices#realStartServiceLocked()
- ActiveServices#requestServiceBindingsLocked()
- ActiveServices#requestServiceBindingLocked()
- ActivityThread$ApplicationThread#scheduleBindService()
接着和启动过程类似。都是最终调用 ActivityThread 来创建 Service 实例并执行 onCreate()
。
Service 的绑定过程会调用 ActiveServices 的 requestServiceBindingsLocked()
。最终调用 ActivityThread$ApplicationThread 的 scheduleBindService()
。然后通过 H 这个 Handler 转向 ActivityThread 的 handleBindService()
ActivityThread#handleBindService()
private void handleBindService(BindServiceData data) { Service s = mServices.get(data.token); data.intent.setExtrasClassLoader(s.getClassLoader()); data.intent.prepareToEnterProcess(); if (!data.rebind) { // 调用 Service 的 onBind 方法 IBinder binder = s.onBind(data.intent); // 调用 AMS 的 publishService。通知客户端已经成功连接 ActivityManagerNative.getDefault().publishService( data.token, data.intent, binder); } else { // 调用 Service 的 onReBind 方法 s.onRebind(data.intent); ActivityManagerNative.getDefault().serviceDoneExecuting( data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0); } ensureJitEnabled(); }复制代码
通知客户端绑定成功
AMS 的 publishService()
调用了 ActiveServices#publishServiceLocked()
void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) { final long origId = Binder.clearCallingIdentity(); 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; for (int conni=r.connections.size()-1; conni>=0; conni--) { ArrayListclist = r.connections.valueAt(conni); for (int i=0; i
看看 InnerConnection 这个类:
LoadedApk.ServiceDispatcher.InnerConnection
private static class InnerConnection extends IServiceConnection.Stub { final WeakReferencemDispatcher; InnerConnection(LoadedApk.ServiceDispatcher sd) { mDispatcher = new WeakReference (sd); } public void connected(ComponentName name, IBinder service) throws RemoteException { LoadedApk.ServiceDispatcher sd = mDispatcher.get(); if (sd != null) { // 调用了 ServiceDispatcher 的 connected sd.connected(name, service); } } }复制代码
LoadedApk.ServiceDispatcher#connected
public void connected(ComponentName name, IBinder service) { if (mActivityThread != null) { // mActivityThread 是 ActivityThread 中的 H,不会为空 // 所以 RunConnection 会运行在主线程中,所以客户端 // ServiceConnection 中的方法是在主线程中被回调的。 // RunConnection 内部也是调用了 doConnected mActivityThread.post(new RunConnection(name, service, 0)); } else { doConnected(name, service); }}复制代码
LoadedApk.ServiceDispatcher#doConnected
public void doConnected(ComponentName name, IBinder service) { ServiceDispatcher.ConnectionInfo old; ServiceDispatcher.ConnectionInfo info; synchronized (this) { old = mActiveConnections.get(name); if (old != null && old.binder == service) { // Huh, already have this one. Oh well! // 绑定的和之前的一样就直接 return return; } if (service != null) { // 新的 service 连接了 // A new service is being connected... set it all up. info = new ConnectionInfo(); info.binder = service; info.deathMonitor = new DeathMonitor(name, service); service.linkToDeath(info.deathMonitor, 0); mActiveConnections.put(name, info); } else { // The named service is being disconnected... clean up. mActiveConnections.remove(name); } if (old != null) { old.binder.unlinkToDeath(old.deathMonitor, 0); } } // If there was an old service, it is now disconnected. if (old != null) { // 将老的断开 mConnection.onServiceDisconnected(name); } // If there is a new service, it is now connected. if (service != null) { // 新的连接 mConnection.onServiceConnected(name, service); } }复制代码
所以绑定只会绑定一次。
停止过程和解除绑定的过程,系统的执行过程是类似的。
BroadcastReceiver 的工作过程
主要包含:
- 广播的注册过程
- 广播的发送和接收过程
定义广播:
public class MyBroadcastReceiver extends BroadcastReceiver { // 此处不可以做耗时操作。参考值:10s以内 @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); }}复制代码
注册广播:
- 静态注册
复制代码
- 动态注册
IntentFilter filter = new IntentFilter();filter.addAction("me.luwenjie.chapter9.receiver");registerReceiver(new MyBroadcastReceiver(),filter);复制代码
发送广播
Intent intent = new Intent("me.luwenjie.chapter9.receiver");sendBroadcast(intent);复制代码
注册过程
静态注册的广播在应用安装时由系统自动完成注册,由 PMS(PackageManagerServcie)来完成整个注册过程。
动态注册从 ContextWrapper 的 registerReceiver()
开始。内部由 ContextImpl 实现。
调用链:
private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId, IntentFilter filter, String broadcastPermission, Handler scheduler, Context context) { IIntentReceiver rd = null; if (mPackageInfo != null && context != null) { if (scheduler == null) { scheduler = mMainThread.getHandler(); } // 从 mPackageInfo 获取 IIntentReceiver 对象 // 这是一个 IPC,BroadcastReceiver 作为 Android // 一个组件是不能直接跨进程传递的,需要通过 IIntentReceiver // 中转。IIntentReceiver 是一个 Binder 接口。 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(); } final Intent intent = ActivityManagerNative.getDefault().registerReceiver( mMainThread.getApplicationThread(), mBasePackageName, rd, filter, broadcastPermission, userId); if (intent != null) { intent.setExtrasClassLoader(getClassLoader()); intent.prepareToEnterProcess(); } return intent; }复制代码
LoadedApk#getReceiverDispatcher
public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r, Context context, Handler handler, Instrumentation instrumentation, boolean registered) { synchronized (mReceivers) { LoadedApk.ReceiverDispatcher rd = null; ArrayMapmap = null; // 已注册就从存储中查找 if (registered) { map = mReceivers.get(context); if (map != null) { rd = map.get(r); } } // 否则新建存储 if (rd == null) { rd = new ReceiverDispatcher(r, context, handler, instrumentation, registered); if (registered) { if (map == null) { map = new ArrayMap (); mReceivers.put(context, map); } map.put(r, rd); } } else { rd.validate(context, handler); } rd.mForgotten = false; return rd.getIIntentReceiver(); } }复制代码
AMS#registerReceiver
public Intent registerReceiver(IApplicationThread caller, String callerPackage, IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { // ... synchronized (this) { // ... ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); if (rl == null) { rl = new ReceiverList(this, callerApp, callingPid, callingUid, userId, receiver); // ... // 将远程的 IIntentReceiver 对象存储 mRegisteredReceivers.put(receiver.asBinder(), rl); } // ... BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission, callingUid, userId); rl.add(bf); // 将 IntentFilter 对象存储 mReceiverResolver.addFilter(bf); // ... return sticky; } }复制代码
发送和接收过程
ContextImpl#sendBroadcast
public void sendBroadcast(Intent intent) { warnIfCallingFromSystemProcess(); String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); intent.prepareToLeaveProcess(this); ActivityManagerNative.getDefault().broadcastIntent( mMainThread.getApplicationThread(), intent, resolvedType, null, Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, false, getUserId()); }复制代码
AMS 内部最终调用了 broadcastIntentLocked()
系统从 Android 3.1 开始为 Intent 添加了 2 个标记:
- FLAG_INCLUDE_STOPPED_PACKAGES
包含已经停止的应用,广播会发送给已经停止的应用
- FLAG_EXCLUDE_STOPPED_PACKAGES
不包含已经停止的应用,广播不会发送给已经停止的应用
系统为所有广播默认添加了 FLAG_EXCLUDE_STOPPED_PACKAGES
。
final int broadcastIntentLocked(ProcessRecord callerApp, String callerPackage, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions, boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) { intent = new Intent(intent); // By default broadcasts do not go to stopped apps. // 默认情况下,广播不会发送给已经停止的应用 // intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); // 根据 intentFilter 查找出匹配的广播接收者并经过一系列的条件过滤。 // 最终将满足条件的广播接收者添加到 BroadcastQueue 中,BroadcastQueue // 就会将广播发送给相应的广播接收者。 // ... if ((receivers != null && receivers.size() > 0) || resultTo != null) { BroadcastQueue queue = broadcastQueueForIntent(intent); BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, callerPackage, callingPid, callingUid, resolvedType, requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode, resultData, resultExtras, ordered, sticky, false, userId); boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); if (!replaced) { queue.enqueueOrderedBroadcastLocked(r); // 将广播发送给相应的接收者 queue.scheduleBroadcastsLocked(); } } else { // There was nobody interested in the broadcast, but we still want to record // that it happened. if (intent.getComponent() == null && intent.getPackage() == null && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { // This was an implicit broadcast... let's record it for posterity. addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0); } } return ActivityManager.BROADCAST_SUCCESS; }复制代码
com.android.server.am.BroadcastQueue#scheduleBroadcastsLocked
public void scheduleBroadcastsLocked() { if (mBroadcastsScheduled) { return; } // 给内部的 Handler 发送了一条 msg。该 Handler 运行在主线程 mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this)); mBroadcastsScheduled = true; }复制代码
com.android.server.am.BroadcastQueue#processNextBroadcast
final void processNextBroadcast(boolean fromMsg) { synchronized(mService) { BroadcastRecord r; mService.updateCpuStats(); if (fromMsg) { mBroadcastsScheduled = false; } // First, deliver any non-serialized broadcasts right away. // 先分发无序广播。无序广播存储在 mParallelBroadcasts 中。 while (mParallelBroadcasts.size() > 0) { r = mParallelBroadcasts.remove(0); r.dispatchTime = SystemClock.uptimeMillis(); r.dispatchClockTime = System.currentTimeMillis(); final int N = r.receivers.size(); // 遍历 for (int i=0; i
最终调用
LoadedApk$ReceiverDispatcher#performReceive
public void performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser) { // 新建 Args 对象 final Args args = new Args(intent, resultCode, data, extras, ordered, sticky, sendingUser); // ... // 通过 ActivityThread 中的 H 执行 args 中的逻辑 if (intent == null || !mActivityThread.post(args)) { if (mRegistered && ordered) { IActivityManager mgr = ActivityManagerNative.getDefault(); args.sendFinished(mgr); } } } }复制代码
Arg 中的 run():
public void run() { // ... try { ClassLoader cl = mReceiver.getClass().getClassLoader(); intent.setExtrasClassLoader(cl); intent.prepareToEnterProcess(); setExtrasClassLoader(cl); receiver.setPendingResult(this); // 调用了 onReceive receiver.onReceive(mContext, intent); } if (receiver.getPendingResult() != null) { finish(); } } }复制代码
ContentProvider 的工作过程
ContentProvider 是一种内容共享型组件,通过 Binder 向其他组件或应用提供数据。
启动
当 ContentProvider 所在的进程启动时,ContenProvider 会同时被启动并被发布到 AMS 中。
这时 ContentProvider 的 onCreate()
要先于 Application 的 onCreate()
执行。
ActivityThread#handleBindApplication 中的代码片段:
// ....// 先初始化 ContentProvidersif (!ArrayUtils.isEmpty(data.providers)) {installContentProviders(app, data.providers); // For process that contains content providers, we want to // ensure that the JIT is enabled "at some point". mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);} // ...// 接着调用 application 的 onCreatemInstrumentation.callApplicationOnCreate(app);复制代码
ContentProvider 启动完成后,外界就可以通过它提供的增删改查四个接口来操作 ContentProvider 中的数据。
即通过 Binder 调用insert
、delete
、update
、query
四个方法。 外界无法直接访问 ContentProvider,只能通过 AMS 根据 Uri 来获取对应的 ContentProvider 的 Binder 接口 IContentProvider,然后通过它访问内部的数据。
单实例
一般来说,ContentProvider 都是单实例。
这由属性android:multiprocess
决定,false 即为单实例,默认为 false。 开启多实例时,在每个调用者的进程中都存在一个 ContentProvider 对象。
在实际开发中,并未出现多实例的具体使用场景,官方解释这样可以减少进程间通信的开销。访问 ContentProvider
需要通过 ContentResolver。这是个抽象类。实现类是 ContextImpl$ApplicationContentResolver
public abstract class ContentResolver复制代码
当 ContentProvider 所在的线程为启动时,第一次访问它就会触发 ContentProvider 的创建。通过 ContentResolver 的四个方法都可以触发。
ContextImpl$ApplicationContentResolver#query
public final @Nullable Cursor query(final @RequiresPermission.Read @NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder, @Nullable CancellationSignal cancellationSignal) { // .... try { // ... // Wrap the cursor object into CursorWrapperInner object. // 获取 IContentProvider 对象 final IContentProvider provider = (stableProvider != null) ? stableProvider : acquireProvider(uri); // ... return wrapper; } catch (RemoteException e) { } finally { } }复制代码
acquireProvider()
最终调用了 ActivityThread 的 acquireProvider()
。
ActivityThread#acquireProvider
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; } // 当 2 个进程同时请求时,只会保证第一个成功。无法用锁,因为请求需要很长时间,同一个进程可能会重新进入锁。 // 没有查找到就发送一个进程间请求给 AMS 让其启动 IActivityManager.ContentProviderHolder holder = null; try { holder = ActivityManagerNative.getDefault().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 是如何启动 ContentProvider的?
上面的 getContentProvider()
调用了 getContentProviderImpl()
AMS#getContentProviderImpl
private ContentProviderHolder getContentProviderImpl(IApplicationThread caller, String name, IBinder token, boolean stable, int userId) {// ... // 通过 startProcessLocked 启动进程proc = startProcessLocked(cpi.processName, cpr.appInfo, false, 0, "content provider", new ComponentName(cpi.applicationInfo.packageName, cpi.name), false, false, false); // ... return cpr != null ? cpr.newHolder(conn) : null; }复制代码
startProcessLocked()
的内部通过 Progress 的 start()
来完成一个新进程的启动。
新进程启动后的入口方法就是 ActivityThread 的 main()
。 然后就和上述 启动过程 一样。