Android Applicaion組件創建的源代碼
- 1. 序列圖
- 2. Application創建過程源代碼
- 2.1 ActivityThread初始化
- 2.2 ActivityThread的attach(...)函數
- 2.3 ActivityManagerService的attachApplication函數
- 2.4 ActivityManagerService的attachApplicationLocked函數
- 2.5 ActivityThread的handleBindApplication函數
- 2.6 Instrumentation 的callApplicationOnCreate函數和newApplication函數
- 3. 另附兩篇Application源碼分析過程中的文章
- 4. 參考文章
1. 序列圖
1.1 簡化版序列圖
1.2 完整版序列圖
2. Application創建過程源代碼
2.1 ActivityThread初始化
public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
// Install selective syscall interception
// 安裝選擇性的系統調用攔截
AndroidOs.install();
// CloseGuard defaults to true and can be quite spammy. We
// disable it here, but selectively enable it later (via
// StrictMode) on debug builds, but using DropBox, not logs.
/*
CloseGuard(工具類,用來記錄資源泄露的場景,比如使用完的資源(比如cursor/fd)沒有正常關閉),默認爲true,
並且可能是垃圾郵件。 我們在這裏禁用它,可以在調試版本中有選擇地啓用它(通過StrictMode),使用DropBox而不是日誌。
*/
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
// Make sure TrustedCertificateStore looks in the right place for CA certificates
// 確保TrustedCertificateStore可以正確查找到CA證書(數字證書)
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
// Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line.
// It will be in the format "seq=114"
/*
找到命令行中的值{@link #PROC_START_SEQ_IDENT},值的格式爲"seq=114"
*/
long startSeq = 0;
if (args != null) {
for (int i = args.length - 1; i >= 0; --i) {
if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
startSeq = Long.parseLong(
args[i].substring(PROC_START_SEQ_IDENT.length()));
}
}
}
//實例化ActivityThread
ActivityThread thread = new ActivityThread();
//調用attach()
thread.attach(false, startSeq);
//創建主線程Handler
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
// End of event ActivityThreadMain.
// ActivityThreadMain事件結束
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
//循環的從消息隊列中通過MessageQueue的next方法獲取Message
//UI顯示刷新通過Handler處理,Looper會阻塞但不會卡死
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
2.2 ActivityThread的attach(…)函數
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());
//獲取ActivityManager Service代理對象
final IActivityManager mgr = ActivityManager.getService();
try {
//通知AMS(Android中系統服務,可統一調度所有應用的Activity)進行application的初始化
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
// Watch for getting close to heap limit.
// 注意接近堆限制
BinderInternal.addGcWatcher(new Runnable() {
@Override public void run() {
if (!mSomeActivitiesChanged) {
return;
}
Runtime runtime = Runtime.getRuntime();
long dalvikMax = runtime.maxMemory();
long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
if (dalvikUsed > ((3*dalvikMax)/4)) {
if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
+ " total=" + (runtime.totalMemory()/1024)
+ " used=" + (dalvikUsed/1024));
mSomeActivitiesChanged = false;
try {
ActivityTaskManager.getService().releaseSomeActivities(mAppThread);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
});
} else {
// Don't set application object here -- if the system crashes,
// we can't display an alert, we just want to die die die.
/*
不要在這裏設置應用程序對象-如果系統崩潰,我們將無法顯示提醒,我們只是想關閉。
*/
android.ddm.DdmHandleAppName.setAppName("system_process",
UserHandle.myUserId());
try {
//創建Instrumentation,負責跟蹤Application在Activity的生命週期
mInstrumentation = new Instrumentation();
mInstrumentation.basicInit(this);
ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo);
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
mInitialApplication.onCreate();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate Application():" + e.toString(), e);
}
}
ViewRootImpl.ConfigChangedCallback configChangedCallback
= (Configuration globalConfig) -> {
synchronized (mResourcesManager) {
// We need to apply this change to the resources immediately, because upon returning
// the view hierarchy will be informed about it.
/*
我們需要立即將此更改應用於資源,因爲返回後,視圖層次結構將被提示
*/
if (mResourcesManager.applyConfigurationToResourcesLocked(globalConfig,
null /* compat */)) {
updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(),
mResourcesManager.getConfiguration().getLocales());
// This actually changed the resources! Tell everyone about it.
// 改變了資源
if (mPendingConfiguration == null
|| mPendingConfiguration.isOtherSeqNewer(globalConfig)) {
mPendingConfiguration = globalConfig;
sendMessage(H.CONFIGURATION_CHANGED, globalConfig);
}
}
}
};
ViewRootImpl.addConfigCallback(configChangedCallback);
}
2.3 ActivityManagerService的attachApplication函數
public final void attachApplication(IApplicationThread thread, long startSeq) {
synchronized (this) {
//獲取遠程Binder調用端的Pid,Uid
int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
//清空遠程調用端的Uid和Pid,用當前本地進程的Uid和Pid替代
final long origId = Binder.clearCallingIdentity();
//調用attachApplicationLocked()
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
//通過origId變量,還原遠程Binder調用端的Uid和Pid信息
Binder.restoreCallingIdentity(origId);
}
}
2.4 ActivityManagerService的attachApplicationLocked函數
private final boolean attachApplicationLocked(IApplicationThread thread, int pid, int callingUid, long startSeq) {
//...
//ActivityThread啓動application
thread.bindApplication(processName, appInfo, providers,
instr2.mClass,
profilerInfo, instr2.mArguments,
instr2.mWatcher,
instr2.mUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.isPersistent(),
new Configuration(app.getWindowProcessController().getConfiguration()),
app.compat, getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, autofillOptions, contentCaptureOptions);
//...
}
2.5 ActivityThread的handleBindApplication函數
private void handleBindApplication(AppBindData data) {
// Register the UI Thread as a sensitive thread to the runtime.
// 將UI線程註冊爲虛擬機(VMRuntime)
VMRuntime.registerSensitiveThread();
// In the case the stack depth property exists, pass it down to the runtime.
// 如果存在堆棧深度屬性,則將其傳遞給虛擬機
String property = SystemProperties.get("debug.allocTracker.stackDepth");
if (property.length() != 0) {
VMDebug.setAllocTrackerStackDepth(Integer.parseInt(property));
}
if (data.trackAllocation) {
DdmVmInternal.enableRecentAllocations(true);
}
// Note when this process has started.
// 注意進程開始時間
Process.setStartTimes(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
mBoundApplication = data;
mConfiguration = new Configuration(data.config);
mCompatConfiguration = new Configuration(data.config);
mProfiler = new Profiler();
String agent = null;
if (data.initProfilerInfo != null) {
mProfiler.profileFile = data.initProfilerInfo.profileFile;
mProfiler.profileFd = data.initProfilerInfo.profileFd;
mProfiler.samplingInterval = data.initProfilerInfo.samplingInterval;
mProfiler.autoStopProfiler = data.initProfilerInfo.autoStopProfiler;
mProfiler.streamingOutput = data.initProfilerInfo.streamingOutput;
if (data.initProfilerInfo.attachAgentDuringBind) {
agent = data.initProfilerInfo.agent;
}
}
// send up app name; do this *before* waiting for debugger
// 發送app名稱;在此之前等待調試器(debugger)
Process.setArgV0(data.processName);
android.ddm.DdmHandleAppName.setAppName(data.processName,
UserHandle.myUserId());
VMRuntime.setProcessPackageName(data.appInfo.packageName);
// Pass data directory path to ART. This is used for caching information and
// should be set before any application code is loaded.
// 將數據目錄路徑傳遞到ART(Android Runtime)。用於緩存信息,應在加載任何應用程序代碼之前進行設置。
// Android 4.4中可選擇性開啓ART,Android 5.0後完全替代Dalvik虛擬機
VMRuntime.setProcessDataDirectory(data.appInfo.dataDir);
if (mProfiler.profileFd != null) {
mProfiler.startProfiling();
}
// If the app is Honeycomb MR1 or earlier, switch its AsyncTask
// implementation to use the pool executor. Normally, we use the
// serialized executor as the default. This has to happen in the
// main thread so the main looper is set right.
/*
如果應用程序是Honeycomb MR1或更早版本,需切換其AsyncTask實現以使用池執行程序。
通常,我們使用序列化的執行程序作爲默認值。這必須在主線程中發生,因此主Looper需設置正確。
*/
if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
// Let the util.*Array classes maintain "undefined" for apps targeting Pie or earlier.
// 讓util.*Array中的類文件維護Android Q或者更早版本的未定義App
UtilConfig.setThrowExceptionForUpperArrayOutOfBounds(
data.appInfo.targetSdkVersion >= Build.VERSION_CODES.Q);
Message.updateCheckRecycle(data.appInfo.targetSdkVersion);
// Prior to P, internal calls to decode Bitmaps used BitmapFactory,
// which may scale up to account for density. In P, we switched to
// ImageDecoder, which skips the upscale to save memory. ImageDecoder
// needs to still scale up in older apps, in case they rely on the
// size of the Bitmap without considering its density.
/*
在P之前,對Bitmap進行內部解碼的調用使用了BitmapFactory,它可以擴展以解決密度問題。
在P中,我們切換到ImageDecoder,它跳過了消耗高的代碼以節省內存。 如果舊版本的應用程序
依賴於位圖的大小而不考慮其密度,則ImageDecoder仍需要在舊版應用程序中進行擴展
*/
ImageDecoder.sApiLevel = data.appInfo.targetSdkVersion;
/*
* Before spawning a new process, reset the time zone to be the system time zone.
* This needs to be done because the system time zone could have changed after the
* the spawning of this process. Without doing this this process would have the incorrect
* system time zone.
*/
/*
在產生新進程之前,需將時區重置爲系統時區,因爲系統時區可能在該進程產生後已更改。
如果不這樣做,此過程可能會有不正確的系統時區。
*/
TimeZone.setDefault(null);
/*
* Set the LocaleList. This may change once we create the App Context.
*/
/*
設置LocaleList。 一旦創建了應用上下文,LocaleList可能會改變
*/
LocaleList.setDefault(data.config.getLocales());
synchronized (mResourcesManager) {
/*
* Update the system configuration since its preloaded and might not
* reflect configuration changes. The configuration object passed
* in AppBindData can be safely assumed to be up to date
*/
/*
由於系統配置已預先加載,因此可能會更新,因此可能無法反映配置更改。
可以安全地假定AppBindData中傳遞的配置對象是最新的
*/
mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo);
mCurDefaultDisplayDpi = data.config.densityDpi;
// This calls mResourcesManager so keep it within the synchronized block.
// 調用mResourcesManager,並將其保留在同步塊中
applyCompatConfiguration(mCurDefaultDisplayDpi);
}
data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
if (agent != null) {
handleAttachAgent(agent, data.info);
}
/**
* Switch this process to density compatibility mode if needed.
*/
if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
== 0) {
mDensityCompatMode = true;
Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
}
updateDefaultDensity();
final String use24HourSetting = mCoreSettings.getString(Settings.System.TIME_12_24);
Boolean is24Hr = null;
if (use24HourSetting != null) {
is24Hr = "24".equals(use24HourSetting) ? Boolean.TRUE : Boolean.FALSE;
}
// null : use locale default for 12/24 hour formatting,
// false : use 12 hour format,
// true : use 24 hour format.
/*
null:使用默認環境下的12/24小時格式,
false:使用12小時格式,
true:使用24小時格式。
*/
DateFormat.set24HourTimePref(is24Hr);
updateDebugViewAttributeState();
StrictMode.initThreadDefaults(data.appInfo);
StrictMode.initVmDefaults(data.appInfo);
if (data.debugMode != ApplicationThreadConstants.DEBUG_OFF) {
// XXX should have option to change the port.
// XXX應該可以選擇更改端口
Debug.changeDebugPort(8100);
if (data.debugMode == ApplicationThreadConstants.DEBUG_WAIT) {
Slog.w(TAG, "Application " + data.info.getPackageName()
+ " is waiting for the debugger on port 8100...");
IActivityManager mgr = ActivityManager.getService();
try {
mgr.showWaitingForDebugger(mAppThread, true);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
Debug.waitForDebugger();
try {
mgr.showWaitingForDebugger(mAppThread, false);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
} else {
Slog.w(TAG, "Application " + data.info.getPackageName()
+ " can be debugged on port 8100...");
}
}
// Allow binder tracing, and application-generated systrace messages if we're profileable.
// 允許Binder(進程間通信機制)跟蹤,則允許綁定程序跟蹤和應用程序生成的系統跟蹤消息
boolean isAppProfileable = data.appInfo.isProfileableByShell();
Trace.setAppTracingAllowed(isAppProfileable);
if (isAppProfileable && data.enableBinderTracking) {
Binder.enableTracing();
}
// Initialize heap profiling.
// 初始化堆分析
if (isAppProfileable || Build.IS_DEBUGGABLE) {
nInitZygoteChildHeapProfiling();
}
// Allow renderer debugging features if we're debuggable.
// 如果我們是可調試的,則允許渲染器調試功能
boolean isAppDebuggable = (data.appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
HardwareRenderer.setDebuggingEnabled(isAppDebuggable || Build.IS_DEBUGGABLE);
HardwareRenderer.setPackageName(data.appInfo.packageName);
/**
* Initialize the default http proxy in this process for the reasons we set the time zone.
*/
//由於我們設置時區的原因,在此過程中初始化默認的http代理。
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Setup proxies");
final IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
if (b != null) {
// In pre-boot mode (doing initial launch to collect password), not
// all system is up. This includes the connectivity service, so don't
// crash if we can't get it.
/*
在預引導模式下(進行初始啓動以收集密碼),並非所有系統都已啓動。 這包括連接服務,因此如果我們無法獲得連接,請不要崩潰
*/
final IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
try { Proxy.setHttpProxySystemProperty(service.getProxyForNetwork(null));
} catch (RemoteException e) {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
throw e.rethrowFromSystemServer();
}
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
// Instrumentation info affects the class loader, so load it before
// setting up the app context.
/*
Instrumentation信息會影響類加載器,所以需要在設置應用程序上下文之前加載它。
*/
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);
}
// Warn of potential ABI mismatches.
// 警告潛在的ABI(Application Binary Interface,應用程序提供應用程序二進制接口,
// 包含一系列的系統調用和使用這些系統調用的方法)不匹配。
if (!Objects.equals(data.appInfo.primaryCpuAbi, ii.primaryCpuAbi)
|| !Objects.equals(data.appInfo.secondaryCpuAbi, ii.secondaryCpuAbi)) {
Slog.w(TAG, "Package uses different ABI(s) than its instrumentation: "
+ "package[" + data.appInfo.packageName + "]: "
+ data.appInfo.primaryCpuAbi + ", " + data.appInfo.secondaryCpuAbi
+ " instrumentation[" + ii.packageName + "]: "
+ ii.primaryCpuAbi + ", " + ii.secondaryCpuAbi);
}
mInstrumentationPackageName = ii.packageName;
mInstrumentationAppDir = ii.sourceDir;
mInstrumentationSplitAppDirs = ii.splitSourceDirs;
mInstrumentationLibDir = getInstrumentationLibrary(data.appInfo, ii);
mInstrumentedAppDir = data.info.getAppDir();
mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();
mInstrumentedLibDir = data.info.getLibDir();
} else {
ii = null;
}
//創建上下文對象
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
updateLocaleListFromAppContext(appContext,
mResourcesManager.getConfiguration().getLocales());
if (!Process.isIsolated()) {
final int oldMask = StrictMode.allowThreadDiskWritesMask();
try {
setupGraphicsSupport(appContext);
} finally {
StrictMode.setThreadPolicyMask(oldMask);
}
} else {
HardwareRenderer.setIsolatedProcess(true);
}
// Install the Network Security Config Provider. This must happen before the application
// code is loaded to prevent issues with instances of TLS objects being created before
// the provider is installed.
/*
安裝網絡安全配置Provider。必須在加載應用代碼之前完成,以防止在安裝provider之前
創建傳輸層安全協議(Transport Layer Security,TLS)對象實例的問題
*/
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "NetworkSecurityConfigProvider.install");
NetworkSecurityConfigProvider.install(appContext);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
// Continue loading instrumentation.
// 繼續加載instrumentation(Android系統裏面的一套控制方法或者”鉤子“,用於在正常的生命週期之外控制控件的運行)
if (ii != null) {
ApplicationInfo instrApp;
try {
instrApp = getPackageManager().getApplicationInfo(ii.packageName, 0,
UserHandle.myUserId());
} catch (RemoteException e) {
instrApp = null;
}
if (instrApp == null) {
instrApp = new ApplicationInfo();
}
ii.copyTo(instrApp);
instrApp.initForUser(UserHandle.myUserId());
final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
appContext.getClassLoader(), false, true, false);
// The test context's op package name == the target app's op package name, because
// the app ops manager checks the op package name against the real calling UID,
// which is what the target package name is associated with.
/*
測試上下文的包名==目標應用程序的包名,因爲應用程序操作管理器會根據
真實的調用UID(即目標程序包名稱與之關聯)來檢查包名。
*/
final ContextImpl instrContext = ContextImpl.createAppContext(this, pi,
appContext.getOpPackageName());
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);
if (mProfiler.profileFile != null && !ii.handleProfiling
&& mProfiler.profileFd == null) {
mProfiler.handlingProfiling = true;
final File file = new File(mProfiler.profileFile);
file.getParentFile().mkdirs();
Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
}
} else {
//創建Instrumentation,負責跟蹤Application在Activity的生命週期
mInstrumentation = new Instrumentation();
mInstrumentation.basicInit(this);
}
if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
} else {
// Small heap, clamp to the current growth limit and let the heap release
// pages after the growth limit to the non growth limit capacity. b/18387825
/*
小堆,將其限制在當前的增長限制之內,然後讓堆在增長限制達到非增長限制容量之後釋放頁面
*/
dalvik.system.VMRuntime.getRuntime().clampGrowthLimit();
}
// Allow disk access during application and provider setup. This could
// block processing ordered broadcasts, but later processing would
// probably end up doing the same disk access.
/*
在應用程序和provider程序設置期間允許磁盤訪問。這可能會阻止處理有序廣播,
但是以後的處理可能最終會進行相同的磁盤訪問。
*/
Application app;
final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
final StrictMode.ThreadPolicy writesAllowedPolicy = StrictMode.getThreadPolicy();
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進行完全備份或還原,則需要在受限環境中通過基本application類將其啓動
// 創建Application對象
app = data.info.makeApplication(data.restrictedBackupMode, null);
// Propagate autofill compat state
// 傳播自動填充兼容狀態
app.setAutofillOptions(data.autofillOptions);
// Propagate Content Capture options
// 傳播內容捕獲選項
app.setContentCaptureOptions(data.contentCaptureOptions);
mInitialApplication = app;
// don't bring up providers in restricted mode; they may depend on the
// app's custom Application class
/*
不要以受限模式啓動providers;它們可能取決於應用程序的自定義Application類
*/
if (!data.restrictedBackupMode) {
if (!ArrayUtils.isEmpty(data.providers)) {
installContentProviders(app, data.providers);
}
}
// Do this after providers, since instrumentation tests generally start their
// test thread at this point, and we don't want that racing.
/*
在providers(Content Providers,用於共享數據給訪問者)之後執行此操作,通常情況下instrumentation測試會開始其測試線程,並且我們不希望它開啓
*/
try {
//調用Instrumentation的onCreate(),內部是空實現
mInstrumentation.onCreate(data.instrumentationArgs);
}
catch (Exception e) {
throw new RuntimeException(
"Exception thrown in onCreate() of "
+ data.instrumentationName + ": " + e.toString(), e);
}
try {
//調用Instrumentation的callApplicationOnCreate(),內部是調用Application的onCreate
/*
public class Instrumentation {
public void callApplicationOnCreate(Application app) {
app.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 {
// If the app targets < O-MR1, or doesn't change the thread policy
// during startup, clobber the policy to maintain behavior of b/36951662
// 沒看懂
if (data.appInfo.targetSdkVersion < Build.VERSION_CODES.O_MR1
|| StrictMode.getThreadPolicy().equals(writesAllowedPolicy)) {
StrictMode.setThreadPolicy(savedPolicy);
}
}
// Preload fonts resources
// 預加載字體資源
FontsContract.setApplicationContextForResources(appContext);
if (!Process.isIsolated()) {
try {
final ApplicationInfo info =
getPackageManager().getApplicationInfo(
data.appInfo.packageName,
PackageManager.GET_META_DATA /*flags*/,
UserHandle.myUserId());
if (info.metaData != null) {
final int preloadedFontsResource = info.metaData.getInt(
ApplicationInfo.METADATA_PRELOADED_FONTS, 0);
if (preloadedFontsResource != 0) {
data.info.getResources().preloadFonts(preloadedFontsResource);
}
}
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
2.6 Instrumentation 的callApplicationOnCreate函數和newApplication函數
public void callApplicationOnCreate(Application app) {
app.onCreate();
}
public Application newApplication(ClassLoader cl, String className, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = getFactory(context.getPackageName())
.instantiateApplication(cl, className);
//調用Application的attach
app.attach(context);
return app;
}
3. 另附兩篇Application源碼分析過程中的文章
- Android源代碼分析之類方法與組件名詞解釋https://blog.csdn.net/qq_26906345/article/details/103694786。
- Android Applicaion組件創建的源代碼流程分析
https://blog.csdn.net/qq_26906345/article/details/103693846。
4. 參考文章
[1]: Android的Handler的簡單理解和使用. https://blog.csdn.net/weixin_43548748/article/details/91128791.
[2]: Android消息處理機制:Handler中sendMessage()方法的幾種重載方法. https://blog.csdn.net/fansl410k/article/details/79425765.
[3]: Android系統服務 —— WMS與AMS. https://www.jianshu.com/p/47eca41428d6.
[4]: Android源碼的Binder權限控制. https://blog.csdn.net/bbmcdull/article/details/52046690.
[5]: Binder進程間通信系統. Android系統源代碼情景分析.
[6]: Android進階(三):Application啓動過程(最詳細&最簡單). https://www.jianshu.com/p/4a8f44b6eecb.
[7]: Application初始化過程,基於android10. https://juejin.im/post/5ddb6b0de51d4523307fca86.
[8]: Android內存優化:DVM和ART原理初探. https://blog.csdn.net/weixin_42336002/article/details/80610555.
[9]: Content Provider組件的實現原理. Android系統源代碼情景分析.
[10]: Android HTTPS、TLS版本支持相關解決方案. https://blog.csdn.net/devrecord/article/details/88580235.
[11]: 不同版本的TLS在Android中的支持情況. https://blog.csdn.net/yanzhenjie1003/article/details/80202476.
[12]: 加密傳輸纔是王道!谷歌在 Android P 上默認啓用 TLS. https://www.oschina.net/news/95202/dns-over-tls-support-in-android-p.
[13]: Android instrumentation原理. https://blog.csdn.net/a19891024/article/details/54342799.
[14]: Instrumentation的理解. https://www.jianshu.com/p/5a7768f22b36.
[15]: Android ABI的淺析. https://www.jianshu.com/p/d2119b3880d8.
[16]: 關於BOOT_COMPLETED廣播-自啓動. https://www.jianshu.com/p/679dc03ee650.
[17]: PackageManagerService原理分析文章合集. https://www.douban.com/note/726553288/.
[18]: PackageManagerService服務框架詳解. https://www.jianshu.com/p/ef058fcfcd30.
[19]: Android 插件化原理解析——Hook機制之AMS&PMS.https://www.jianshu.com/p/8632fdc86009.
[20]: 一篇文章看明白 Android PackageManagerService 工作流程.https://blog.csdn.net/freekiteyu/article/details/82774947.