四大组件之Activity

来源:互联网 发布:2016全国溺水事故数据 编辑:程序博客网 时间:2024/06/05 02:46

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

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

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

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

06-25 13:15:56.485 22075-22075/com.xue.qin.demo.onkeydowntest D/MainActivity: java.lang.Throwable                                                                                  at com.xue.qin.demo.onkeydowntest.MainActivity.onCreate(MainActivity.java:50)                                                                                  at android.app.Activity.performCreate(Activity.java:6270)                                                                                  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1113)                                                                                  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2500)                                                                                  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2613)                                                                                  at android.app.ActivityThread.-wrap11(ActivityThread.java)                                                                                  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1469)                                                                                  at android.os.Handler.dispatchMessage(Handler.java:111)                                                                                  at android.os.Looper.loop(Looper.java:207)                                                                                  at android.app.ActivityThread.main(ActivityThread.java:5692)                                                                                  at java.lang.reflect.Method.invoke(Native Method)                                                                                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908)                                                                                  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

public static void main(String[] args) {        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");        SamplingProfilerIntegration.start();        // 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();        // Set the reporter for event logging in libcore        EventLogger.setReporter(new EventLoggingReporter());        // Make sure TrustedCertificateStore looks in the right place for CA certificates        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());        TrustedCertificateStore.setDefaultUserDirectory(configDir);        Process.setArgV0("<pre-initialized>");        Looper.prepareMainLooper();        ActivityThread thread = new ActivityThread();        thread.attach(false);        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");    }

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

ActivityThread.java中的attach()方法,

final IActivityManager mgr = ActivityManagerNative.getDefault();            try {                mgr.attachApplication(mAppThread);            } catch (RemoteException ex) {                throw ex.rethrowFromSystemServer();            }

代码中没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中的处理如下

 case BIND_APPLICATION:                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");                    AppBindData data = (AppBindData)msg.obj;                    handleBindApplication(data);                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                    break;

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


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

Activity.java

startActivity()

startActivityForResult()代码如下使用。

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

看一下这个方法

Instrumentation.java

execStartActivity()

 int result = ActivityManagerNative.getDefault()                .startActivity(whoThread, who.getBasePackageName(), intent,                        intent.resolveTypeIfNeeded(who.getContentResolver()),                        token, target != null ? target.mEmbeddedID : null,                        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是不一样的。