本文基于Android 9.0(API 28)
1,先在 Activity 中查找
在 Activity 的getSystemService() 方法的代碼如下:
@Override
public Object getSystemService(@ServiceName @NonNull String name) {
if (getBaseContext() == null) {
throw new IllegalStateException(
"System services not available to Activities before onCreate()");
}
if (WINDOW_SERVICE.equals(name)) {
return mWindowManager;
} else if (SEARCH_SERVICE.equals(name)) {
ensureSearchManager();
return mSearchManager;
}
return super.getSystemService(name);
}
1)Activity 檢查發(fā)現(xiàn)如果需要的是 WindowManager 和 SearchManager,則返回其屬性 mWindowManager 和 mSearchManager。WindowManager 最終也是通過 Context 的getSystemService()獲取,而 ensureSearchManager() 在 Activity 中直接創(chuàng)建SearchManager。
2)否則調(diào)用其父類 ContextThemeWrapper對應(yīng)的方法:
@Override
public Object getSystemService(String name) {
if (LAYOUT_INFLATER_SERVICE.equals(name)) {
if (mInflater == null) {
mInflater = LayoutInflater.from(getBaseContext()).cloneInContext(this);
}
return mInflater;
}
return getBaseContext().getSystemService(name);
}
可以看到LayoutInflater.from() 傳入的是 getBaseContext(),這個方法是ContextThemeWrapper 的父類 ContextWrapper 定義的,返回其屬性 mBase(Context類型)。mBase 的賦值有兩個地方:
其一,構(gòu)造方法
public ContextWrapper(Context base) {
mBase = base;
}
通過全局搜索,沒有發(fā)現(xiàn)有用的信息。
其二,
protected void attachBaseContext(Context base) {
if (mBase != null) {
throw new IllegalStateException("Base context already set");
}
mBase = base;
}
這個方法在 Activity 的attach() 方法中調(diào)用:
final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config, String referrer, IVoiceInteractor voiceInteractor,
Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken) {
attachBaseContext(context);
......
}
2,先看 ContextImpl 是如何創(chuàng)建的
我們知道 ActivityThread 的main() 是程序的入口,
public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
// Install selective syscall interception
AndroidOs.install();
....
Looper.prepareMainLooper();
....
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
...
Looper.loop();
}
開始準(zhǔn)備 Looper 處理消息,需要注意到這個attach() 方法,傳入的 system 參數(shù)是false:
@UnsupportedAppUsage
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
...
} else {//主要是創(chuàng)建application,準(zhǔn)備程序所需要的環(huán)境等等
...
}
}
通過 AIDL 獲取ActivityManagerService(繼承于 IActivityManager.Stub) 代理對象,同時調(diào)用attachApplication() 。其內(nèi)部調(diào)用 ApplicationThread(IApplicationThread 類型) 的bindApplication() 方法,最終調(diào)用了attachApplicationLocked()。
@GuardedBy("this")
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid, int callingUid, long startSeq) {
......
// 當(dāng)前application與之前的進程綁定,需要解綁并清空信息
// If this application record is still attached to a previous
// process, clean it up now.
if (app.thread != null) {
handleAppDiedLocked(app, true, true);
}
//準(zhǔn)備其他信息,先不關(guān)注
...
//創(chuàng)建application并綁定
checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(app);
if (app.isolatedEntryPoint != null) {
// This is an isolated process which should just call an entry point instead of
// being bound to an application.
thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
} else if (app.instr != null) {
thread.bindApplication(processName, appInfo, providers,
app.instr.mClass,
profilerInfo, app.instr.mArguments,
app.instr.mWatcher,
app.instr.mUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(getGlobalConfiguration()), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, isAutofillCompatEnabled);
} else {
thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
null, null, null, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(getGlobalConfiguration()), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, isAutofillCompatEnabled);
}
...
//啟動已經(jīng)準(zhǔn)備好的activity ,開始啟動activity
// See if the top visible activity is waiting to run in this process...
if (normalMode) {
try {
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
//準(zhǔn)備需要的service
// Find any services that should be running in this process...
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;
}
}
...
return true;
}
- 調(diào)用了
IApplicationThread的 bindApplication() ,實際上是調(diào)用了ActivityThread內(nèi)部類 ApplicationThread 的 bindApplication()。
public final void bindApplication(String processName, ApplicationInfo appInfo,
List<ProviderInfo> providers, 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, boolean autofillCompatibilityEnabled) {
...
AppBindData data = new AppBindData();
data.processName = processName;
data.appInfo = appInfo;
...
sendMessage(H.BIND_APPLICATION, data);
}
發(fā)送了綁定 application 的消息,最終調(diào)用了 ActivityThread 的 handleBindApplication()。
private void handleBindApplication(AppBindData data) {
// Register the UI Thread as a sensitive thread to the runtime.
//準(zhǔn)備dalvik 需要的數(shù)據(jù)信息
...
//準(zhǔn)備 Instrumentation info
// Instrumentation info affects the class loader, so load it before
// setting up the app context.
final InstrumentationInfo ii;
if (data.instrumentationName != null) {
try {
ii = new ApplicationPackageManager(null, getPackageManager())
.getInstrumentationInfo(data.instrumentationName, 0);
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(
"Unable to find instrumentation info for: " + data.instrumentationName);
}
.....
//創(chuàng)建application,內(nèi)部是使用 ClassLoader 的newInstance() 創(chuàng)建
Application app;
try {
app = data.info.makeApplication(data.restrictedBackupMode, null);
...
}
try {//回調(diào) application 的 onCreate()。
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
if (!mInstrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to create application " + app.getClass().getName()
+ ": " + e.toString(), e);
}
}
} finally {
...
}
...
}
至此,application成功創(chuàng)建,并且比 activity 更早。
2)發(fā)現(xiàn)調(diào)用了 ActivityStackSupervisor(用于輔助管理activity棧) 的 attachApplicationLocked(),其實也是調(diào)用了 realStartActivityLocked() 方法。
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException {
...
//創(chuàng)建啟動 activity 的事務(wù),需要關(guān)注 ClientTransaction
// 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));
// Set desired final state.
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// Schedule transaction.
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
...
}
mService.getLifecycleManager().scheduleTransaction(clientTransaction) 最終會調(diào)用到 ClientTransaction的 schedule()
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
mClient 是 IApplicationThread 類型,其實現(xiàn)類是 ActivityThread 的內(nèi)部類 ApplicationThread。
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
其實是交給 ActivityThread 處理,ActivityThread 沒有實現(xiàn)這個方法,其父類 ClientTransactionHandler 中,
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
使用了 Handler 機制,對應(yīng)的 handleMessage()方法中
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;
會執(zhí)行在ActivityStackSupervisor提交的事務(wù),clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),... ...),看到LaunchActivityItem 這個名字就知道這個適用于啟動 activity 的,其 execute() 方法
@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);
}
調(diào)用到ClientTransactionHandler的 handleLaunchActivity() 方法,實際上執(zhí)行的是ActivityThread的 handleLaunchActivity() 方法——》performLaunchActivity() 方法, performLaunchActivity() 會通過Instrumentation加載 activity 及其所需要的資源(Component等)。
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
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);
}
...
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);
}
} catch (Exception e) {
}
}
...
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);
...
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
...
return activity;
}
到這里,activity 會創(chuàng)建并開始它的生命周期。注意ContextImpl appContext = createBaseContextForActivity(r);,其內(nèi)部
private ContextImpl createBaseContextForActivity(ActivityClientRecord r) {
final int displayId;
try {
displayId = ActivityManager.getService().getActivityDisplayId(r.token);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
ContextImpl appContext = ContextImpl.createActivityContext(
this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig);
final DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
// For debugging purposes, if the activity's package name contains the value of
// the "debug.use-second-display" system property as a substring, then show
// its content on a secondary display if there is one.
String pkgName = SystemProperties.get("debug.second-display.pkg");
if (pkgName != null && !pkgName.isEmpty()
&& r.packageInfo.mPackageName.contains(pkgName)) {
for (int id : dm.getDisplayIds()) {
if (id != Display.DEFAULT_DISPLAY) {
Display display =
dm.getCompatibleDisplay(id, appContext.getResources());
appContext = (ContextImpl) appContext.createDisplayContext(display);
break;
}
}
}
return appContext;
}
看到返回的是ContextImpl類型的 appContext。因此實際上使用的是ContextImpl對象及其實現(xiàn)的方法。
3,getSystemService() 最終使用的是什么
在ContextImpl 的對應(yīng)方法中
@Override
public Object getSystemService(String name) {
return SystemServiceRegistry.getSystemService(this, name);
}
發(fā)現(xiàn)這些服務(wù)都是SystemServiceRegistry管理的,它在靜態(tài)代碼塊中注冊了對應(yīng)的服務(wù)
registerService(Context.LAYOUT_INFLATER_SERVICE, LayoutInflater.class,
new CachedServiceFetcher<LayoutInflater>() {
@Override
public LayoutInflater createService(ContextImpl ctx) {
return new PhoneLayoutInflater(ctx.getOuterContext());
}});
實際上LayoutInflater.from()使用的是PhoneLayoutInflater。相同的還有InputMethodManager,WindowManagerImpl等等。
4,總結(jié)
至此,我們的源碼分析完畢??梢园l(fā)現(xiàn)Context作為父類,抽象了大部分常用到的方法,如getString(),startActivities(),getResources(),getMainLooper(),getSystemService()等等。其子類ContextWhraper也只是作為一個代理,簡單的返回 其屬性 mBase (Context類型) 中對應(yīng)的方法調(diào)用結(jié)果而已。實際上所有的工作都是由ContextImpl來完成。
當(dāng)然在分析的過程中,啟動 Activity 時在Manifest 做如下配置:
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
就能將對應(yīng) Activity 作為程序的主 Activity 的原因還沒有分析,需要后面找時間來完成。