涉及到的关键类:ActivityThread,ContextImp,ActivityManager
涉及到的技术:activity启动流程,hook(也就是动态代理),java反射,AMS的交互过程
ActivityThread:
ActivityThread位于android.app包下,他是安卓应用的真正入口,以下代码拷贝自android SDK 26中,去掉了注释部分
public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
SamplingProfilerIntegration.start();
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
EventLogger.setReporter(new EventLoggingReporter());
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
Process.setArgV0("<pre-initialized>");
//准备ui线程的Looper,这也是为什么我们平时可以直接在ui线程中使用handler的原因,而子线程中必须手工进行初始化。
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
//就是mH,它是一个handler
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
//开始loop,这里面就开始无限循环了,如果这里结束了那么就表示整个应用程序结束了
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
通过这段代码我们可以得到几个知识点,简单进行下总结:
-
安卓应用程序的入口是什么?
ActivityThread?Application?Activity? 想必大家也都知道答案了吧,真正的入口只有一个,就是ActivityThread
-
为什么在子线程中需要手工进行Looper的初始化?
因为在ui线程中,系统已经默认帮我们初始化了,而在子线程中必须手工进行初始化,可以参考HandlerThread
-
安卓不能在ui线程中执行耗时操作,但是在程序的入口处却开始了无限循环,这种现象如何解释?
准确的说不能再ui线程中进行耗时操作,指的是四大组件中的生命周期内不能进行耗时操作。而Looper的无限循环是Handler异步通讯的基础,不能结束,如果结束了,就代表应用程序结束了。ANR的异常检查是在AMS中进行校验的,可以参考 http://blog.youkuaiyun.com/vrix/article/details/54134124
ContextImp:
安卓四大组件运行时的上下文环境,以下代码拷贝自android SDK 26中,去掉了注释部分
代码路径为ActivityThread.handleLaunchActivity() -> performLaunchActivity()
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);
}
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
//开始创建ContextImp
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(