四大组件之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是不一样的。
- 四大组件之Activity
- 四大组件之Activity
- 四大组件之Activity
- 四大组件之Activity
- 四大组件之Activity
- 四大组件之Activity
- 四大组件之Activity
- 四大组件之Activity
- 四大组件之Activity
- 四大组件之Activity
- 四大组件之Activity
- 四大组件之 Activity
- 四大组件之Activity
- 四大组件之Activity
- 四大组件之Activity
- 四大组件之Activity
- 四大组件之 activity
- 四大组件之Activity
- 无锁队列的实现
- 快速排序
- Eclipse连接mysql数据库
- hdu2670
- Thymeleaf 之 内置对象、定义变量、URL参数及标签自定义属性
- 四大组件之Activity
- hdu 2795 billboard(线段树)
- ural1108Heritage
- javaSE_8系列博客——Java语言的特性(五)--接口和继承(2)--定义接口
- java文件读写操作
- 递推的矩阵乘法解决练习1
- 使用Struts2关于页面信息国际化(简单的)
- linux centos下安装pymysql
- 概率论中伯努利分布(bernoulli distribution)介绍及C++11中std::bernoulli_distribution的使用