前言
当我们点击桌面图标启动App,到App显示完成,这中间到底经历了什么呢?了解了这部分内容,将会对Activity、Window、View之间联系与区别加深印象,更好指导我们编写代码。
通过这篇文章,你将了解到:
1、Activity创建到onCreate()、onResume方法执行
2、Application创建到onCreate方法执行
3、Activity生命周期监听
4、Window/WindowManager创建与联系
5、WindowManager addView过程
6、ViewRootImpl创建与View三大过程
7、Android屏幕刷新信号简单了解
Android Main方法
写过JavaSE应用或者其它应用的都知道,一个程序的入口是main()方法,那么Android的main()方法在哪呢?
ActivityThread.java
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);
Process.setArgV0("");
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 thread = new ActivityThread();
thread.attach(false, startSeq);
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();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
当进程被fork出来后,执行main()方法。该方法很短,简短列出关注的地方:
构造ActivityThread实例
开启Looper循环(主线程也就是UI线程的Looper)
Application创建过程
来看看ActivityThread.attach()方法:
@UnsupportedAppUsage
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
android.ddm.DdmHandleAppName.setAppName("",
UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
//mgr 为ActivityManagerService 实例
final IActivityManager mgr = ActivityManager.getService();
try {
//mAppThread 为ApplicationThread
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
//省略
}
}
ActivityManagerService.java 方法
public final void attachApplication(IApplicationThread thread, long startSeq) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
//把IApplicationThread thread对象传递给AMS,AMS通过thread传递数据到当前进程
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
Binder.restoreCallingIdentity(origId);
}
}
在attachApplicationLocked(thread, callingPid, callingUid, startSeq);关注两个点:
1、ActivityThread的bindApplication方法
2、mAtmInternal.attachApplication(app.getWindowProcessController()):
先说第一点:
public final void bindApplication(String processName, ApplicationInfo appInfo,
List 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, AutofillOptions autofillOptions,
ContentCaptureOptions contentCaptureOptions) {
//省略
AppBindData data = new AppBindData();
//省略
//切换到主线程
sendMessage(H.BIND_APPLICATION, data);
}
接着在handleMessage()里接收到H.BIND_APPLICATION信息后调用handleBindApplication(data),该方法里主要关注以下几点:
private void handleBindApplication(AppBindData data) {
//省略
if (ii != null) {
//省略
} else {
//创建Instrumentation 对象,ActivityThread持有该对象引用
//Application、Activity 的创建都是需要调用instrumentation相关方法
mInstrumentation = new Instrumentation();
mInstrumentation.basicInit(this);
}
//省略
Application app;
try {
//A
//info 是LoadedApk类型,顾名思义,存放的是apk包的一些信息,如应用名,数据存储目录等
app = data.info.makeApplication(data.restrictedBackupMode, null);
//省略
try {
//B
//app创建完毕,调用方法通知
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
//