四大组件之Activity

比眉伴天荒 2022-06-13 02:57 292阅读 0赞

四大组件之首Activity,联系图形界面和用户的交互,分下一下启动初始化的过程。

先将调用栈打印出来:在onCreate里执行

  1. Log.d(TAG,Log.getStackTraceString(new Throwable()));

打印出如下的Log,从Lanunch启动Activity。

  1. 06-25 13:15:56.485 22075-22075/com.xue.qin.demo.onkeydowntest D/MainActivity: java.lang.Throwable
  2. at com.xue.qin.demo.onkeydowntest.MainActivity.onCreate(MainActivity.java:50)
  3. at android.app.Activity.performCreate(Activity.java:6270)
  4. at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1113)
  5. at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2500)
  6. at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2613)
  7. at android.app.ActivityThread.-wrap11(ActivityThread.java)
  8. at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1469)
  9. at android.os.Handler.dispatchMessage(Handler.java:111)
  10. at android.os.Looper.loop(Looper.java:207)
  11. at android.app.ActivityThread.main(ActivityThread.java:5692)
  12. at java.lang.reflect.Method.invoke(Native Method)
  13. at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908)
  14. at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:769)

最下面的三行代码就不去分析了,倒数第四行log启动了一个应用线程 android.app.ActivityThread.main 这就是当前的应用的界面刷新线程。继续看调用栈,调用loop当前的主线程的looper启动循环,之后的逻辑大概是看到Handler收到一个信息,然后开始执行handleLaunchActivity(),performLaunActivity(),preformCreate(),onCreate()等函数,在ActivityThread,和Activity中很容易找到这些函数调用。

分析到这,有一个节点就是哪里传递进入的这个消息来创建,分析一下这个节点。OK从程序入口Main()函数开始。看一下做了什么

ActivityThread.java

  1. public static void main(String[] args) {
  2. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
  3. SamplingProfilerIntegration.start();
  4. // CloseGuard defaults to true and can be quite spammy. We
  5. // disable it here, but selectively enable it later (via
  6. // StrictMode) on debug builds, but using DropBox, not logs.
  7. CloseGuard.setEnabled(false);
  8. Environment.initForCurrentUser();
  9. // Set the reporter for event logging in libcore
  10. EventLogger.setReporter(new EventLoggingReporter());
  11. // Make sure TrustedCertificateStore looks in the right place for CA certificates
  12. final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
  13. TrustedCertificateStore.setDefaultUserDirectory(configDir);
  14. Process.setArgV0("<pre-initialized>");
  15. Looper.prepareMainLooper();
  16. ActivityThread thread = new ActivityThread();
  17. thread.attach(false);
  18. if (sMainThreadHandler == null) {
  19. sMainThreadHandler = thread.getHandler();
  20. }
  21. if (false) {
  22. Looper.myLooper().setMessageLogging(new
  23. LogPrinter(Log.DEBUG, "ActivityThread"));
  24. }
  25. // End of event ActivityThreadMain.
  26. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  27. Looper.loop();
  28. throw new RuntimeException("Main thread loop unexpectedly exited");
  29. }

可以看出,创建一个主线程Looper,并loop起来,其间还创建了一个ActivityThread对象,并且调用attach()方法。在这个方法中

ActivityThread.java中的attach()方法,

  1. final IActivityManager mgr = ActivityManagerNative.getDefault();
  2. try {
  3. mgr.attachApplication(mAppThread);
  4. } catch (RemoteException ex) {
  5. throw ex.rethrowFromSystemServer();
  6. }

代码中没mAppThread是ActivitityThread类中直接new出来的对象,其实就是个Binder,可以在进程间通信。

这段代码需要很好的分析,因为它初始化了很多Activity启动必须的东西。都是Binder通信,如果熟悉AIDL的java代码,虽不知道BInder具体原理,但也能猜个差不多,具体怎么通信就不管了,直接上结果。

这段中第一句获得一个IActivityManager 这个东西一看就是个进程间通信的接口,这个getDefault()其实就是获得系统Service,代码看一下就可以。这个系统Service的代码在ActivityManagerService 这个类,继承自 ActivityManagerNative ,上面的调用于是就变成了,

ActivityManagerService .java

调用过程

attachApplication()

attachApplicationLocked()

ActivityThread.java 内部类ApplicationThread

bindApplication()——->sendMessage(H.BIND_APPLICATION, data); H就是处理生命周期的那个一个Handler它的Looper就是刚才main中创建的主线程looper

在H中的处理如下

  1. case BIND_APPLICATION:
  2. Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
  3. AppBindData data = (AppBindData)msg.obj;
  4. handleBindApplication(data);
  5. Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
  6. break;

handleBindApplication中创建了mInstrumentation这个对象。Instrumentation根据注释来说这个类是建立系统与Application之间的桥梁这个意思吧。

分析到这里还是没有看到需要H处理的LAUNCH_ACTIVITY 这个消息。从哪里启动也好,从Launch启动,Launch是系统App,也是通过startAcitvity来启动的。从StartActivy来看一下

Activity.java

startActivity()

startActivityForResult()代码如下使用。

  1. Instrumentation.ActivityResult ar =
  2. mInstrumentation.execStartActivity(
  3. this, mMainThread.getApplicationThread(), mToken, this,
  4. intent, requestCode, options);

看一下这个方法

Instrumentation.java

execStartActivity()

  1. int result = ActivityManagerNative.getDefault()
  2. .startActivity(whoThread, who.getBasePackageName(), intent,
  3. intent.resolveTypeIfNeeded(who.getContentResolver()),
  4. token, target != null ? target.mEmbeddedID : null,
  5. requestCode, 0, null, options);

又来获取系统AcitivityManagerService来启动Activity

startActivity()

startActivityAsUser()

ActivityStarter.java

startActivityMayWait()

startActivityLocked()

startActivityUnchecked()

ActivityStackSupervisor.java

resumeFocusedStackTopActivityLocked()管理栈顶

ActivityStack.java

resumeTopActivityUncheckedLocked()

resumeTopActivityInnerLocked()

startSpecificActivityLocked.java

startSpecificActivityLocked()

realStartActivityLocked()

ActivityThread$ApplicationThread

scheduleLaunchActivity()

sendMessage(H.LAUNCH_ACTIVITY, r); //这里发送了这个message,来启动Activity,之后就进入了Activity的生命周期,生命周期的回调函数都在H这个handler中调用。代码就很好理解了不分析了。

转载一张图,博客地址点击打开链 7.0的源码和书上的5.0是不一样的。Center

发表评论

表情:
评论列表 (有 0 条评论,292人围观)

还没有评论,来说两句吧...

相关阅读