学习目标:
ps:注释还是要看的哈!
换一个角度解析Activity启动流程
之前我写过一篇从另一个角度查看activity的启动流程(从startActivity()入手),要是这篇没看懂,可以查看那篇文章,链接如下 带着你解读Android10.0启动流程源码.
学习内容:
首先问这样一个问题?你们认为APP启动有main方法吗?
有的,绝对有main方法,只是google封装的很好,接下来就来我就带你找找。其实你可以在ActivityThread发现这个main()方法。
//Activity实际上就是一个Handler 我们需要注意这一点
public final class ActivityThread extends ClientTransactionHandler {
//与AMS通信的桥梁,作为服务端,接受AMS的操作然后执行。
final ApplicationThread mAppThread = new ApplicationThread();
//管理Application/Activity生命周期
Instrumentation mInstrumentation;
//主线成轮询
private static Looper sMainLooper;
......
//主方法
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.setEnabled(false);
Environment.initForCurrentUser();
// Make sure TrustedCertificateStore looks in the right place for CA certificates
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
// Call per-process mainline module initialization.
initializeMainlineModules();
Process.setArgV0("<pre-initialized>");
/*************************轮询消息QUEUE******************************/
//初始化Handler中的Looper对象。
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"
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();
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.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Looper.loop();
/*************************轮询消息QUEUE******************************/
throw new RuntimeException("Main thread loop unexpectedly exited");
}
.....
//这个方法就是我们使用handler时想要在主线程创建的时候会调用的方法
//这就就是了为什么我们能通过Looper.getMainLooper()获取到主线程的原因
public static Looper getMainLooper() {
synchronized (Looper.class) {
return sMainLooper;
}
}
@Deprecated
public static void prepareMainLooper() {
//false 当前looper不能手动退出
//true 相反
prepare(false);
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
//myLooper():创建一个looper
sMainLooper = myLooper();
}
}
//AIDL跨进程通信
//这个类通过Binder传到AMS中
private class ApplicationThread extends IApplicationThread.Stub {
......
}
}
前期工作做完了,我们就来说一下,当我们启动APP的时候肯定会先启动一个ApplicationThread,然后再启动一个Activity,所以我们接下来就细细地来看。
创建和启动Application
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
这两句代码调用的如下代码:
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());
//获取到AMS代理对象 IActivityManager,具体实现类是ActivityManagerService
final IActivityManager mgr = ActivityManager.getService();
try {
//所以这里实际调用的是ActivityManagerService.attachApplication()
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 {
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) {
// TODO (b/135719017): Temporary log for debugging IME service.
if (Build.IS_DEBUGGABLE && mHasImeComponent) {
Log.d(TAG, "ViewRootImpl.ConfigChangedCallback for IME, "
+ "config=" + globalConfig);
}
// 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);
}
ActivityManagerService
public class ActivityManagerService extends IActivityManager.Stub
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
@Override
public final void attachApplication(IApplicationThread thread, long startSeq) {
if (thread == null) {
throw new SecurityException("Invalid application interface");
}
synchronized (this) {
//当前进程的pid
int callingPid = Binder.getCallingPid();
//当前进程的uid
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
Binder.restoreCallingIdentity(origId);
}
}
......
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
int pid, int callingUid, long startSeq) {
// Find the application record that is being attached... either via
// the pid if we are running in multiple processes, or just pull the
// next app record if we are emulating process with anonymous threads.
// ProcessRecord 进程的记录者,相当于数据类
ProcessRecord app;
.............
if (mPlatformCompat != null) {
mPlatformCompat.resetReporting(app.info);
}
final ProviderInfoList providerList = ProviderInfoList.fromList(providers);
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

本文详细剖析了Android应用的启动过程,从ActivityThread的main方法开始,讲解了如何找到并执行main方法,接着阐述了Application的创建和启动流程,包括ApplicationThread的attach、bindApplication以及Application的onCreate方法。然后,文章深入探讨了Activity的创建和启动,解释了如何通过Instrumentation创建Activity,最后总结了Activity的onCreate()方法调用。整个过程揭示了Android系统如何从底层到上层启动一个应用及其组件。

4353

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



