Android Applicaion组件创建的源代码
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.
6997

被折叠的 条评论
为什么被折叠?



