Android Hello world程序再分析【Android程序的启动流程】
2016-07-25 13:12
417 查看
HelloWorld几乎是每一个程序员学习过程中必会遇到的,所谓温故而知新,今天我们来深入了解一下Android中的helloworld程序。
首先,在eclipse中新建一个Android项目:
![](http://img.blog.csdn.net/20160725131923601)
然后在MainActivity的onCreate方法中打一个断点
![](http://img.blog.csdn.net/20160725132022197)
然后调试,进入调试界面,在调试界面中可以看到这样的东西,这里就是我们的程序运行时的方法栈
![](http://img.blog.csdn.net/20160725132123352)
将这里的方法划分为几个部分
![](http://img.blog.csdn.net/20160725132527322)
如图中所示:
Android程序启动流程大约可以分为6个部分:
zygote孵化
执行ActivityThread的main方法
执行main方法,轮询
轮询到消息,派发消息
实例化并启动Activity
调用Activity的onCreate方法
接下来结合源码深入分析整个启动流程
1,Zygote孵化:Zygote是Android中第一个DalvikVM,在系统启动时(开机)就启动了,这里这个步骤是启动这个HelloWorld程序,Zygote孵化出一个新的进程(也就是DalvikVM)
2,通过反射找到ActivityThread的main方法,并调用( invoke)
3,执行ActivityThread的main方法,像所有的java程序一样,Android程序也是从main方法中开始的。这里主要干的事情就是通过Android的消息机制(Looper+Handler+Message)将主线程变成一个轮询线程,不断地从消息队列(MessageQueue)中获取消息(Message)并派发消息(dispatchMessage())。不明白消息机制的童靴可以看看我另外一篇博客:(自己动手写消息机制)
源码位于:frameworks\base\core\java\android\app\ActivityThread.java
源码位于:frameworks\base\core\java\android\os\Looper.java
4,步骤3中的轮询(Looper)获取到了一个消息(Message),这个Message是ActivityThread中的成员H(H是一个Handler)发来的。这个步骤获取到消息,派发消息,这个消息的处理事件就是启动一个Activity,即是调用ActivityThread中的handlerLaunchActivity()方法,辗转调用
performLaunchActivity()方法。
H是ActivityThread中的一个嵌套类,在ActivityThread的main方法中,通过IPC告诉AMS要启动一个Activity,最后调用了ActivityThread中的handlerLaunchActivity()方法
5,步骤4中的performLaunchActivity()方法调用了Instrumentation的callActivityOnCreate()方法,实际上,ActivityThread并没有直接管理Activity,而是通过Instrumentation间接管理Activity,这种关系就像是,ActivityThread是一个外交官,负责与ActivityManagerService沟通,当AMS让ActivityThread启动一个Activity或者rusume一个Activity的时候,ActivityThread就告诉Instrumentation,“帮我启动某某某Activity”,然后Instrumentation就启动相应的Activity,Instrumentation负责实例化Activity并管理Activity的声明周期。
6,MainActivity的onCreate()方法。开发者重写的方法。
首先,在eclipse中新建一个Android项目:
然后在MainActivity的onCreate方法中打一个断点
然后调试,进入调试界面,在调试界面中可以看到这样的东西,这里就是我们的程序运行时的方法栈
将这里的方法划分为几个部分
如图中所示:
Android程序启动流程大约可以分为6个部分:
zygote孵化
执行ActivityThread的main方法
执行main方法,轮询
轮询到消息,派发消息
实例化并启动Activity
调用Activity的onCreate方法
接下来结合源码深入分析整个启动流程
1,Zygote孵化:Zygote是Android中第一个DalvikVM,在系统启动时(开机)就启动了,这里这个步骤是启动这个HelloWorld程序,Zygote孵化出一个新的进程(也就是DalvikVM)
2,通过反射找到ActivityThread的main方法,并调用( invoke)
3,执行ActivityThread的main方法,像所有的java程序一样,Android程序也是从main方法中开始的。这里主要干的事情就是通过Android的消息机制(Looper+Handler+Message)将主线程变成一个轮询线程,不断地从消息队列(MessageQueue)中获取消息(Message)并派发消息(dispatchMessage())。不明白消息机制的童靴可以看看我另外一篇博客:(自己动手写消息机制)
源码位于:frameworks\base\core\java\android\app\ActivityThread.java
public static void main(String[] args) { ...省略部分我看不懂的代码(hah) Looper.prepareMainLooper(); ... Looper.loop();//开始轮询 //一般来说程序不会运行到这一行,为什么不会运行到这里呢,我们去看看Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }
源码位于:frameworks\base\core\java\android\os\Looper.java
public static void loop() { final Looper me = myLooper();//获取当前线程的Looper,main方法中Looper.prepareMainLooper();已经初始化了当前线程的Looper if (me == null) { //抛出异常说明没有调用Looper.prepare()来初始化Looper throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } final MessageQueue queue = me.mQueue;//获取消息队列 ... for (;;) {//这里就是一个死循环,这里我不明白为什么不用while,两者有什么区别,知道的童靴请告诉我一声哈 Message msg = queue.next(); // might block if (msg == null) { // No message indicates that the message queue is quitting. return;//只有消息为null的情况下才会退出循环 } ...删繁就简,抓住问题的核心 msg.target.dispatchMessage(msg);//派发消息的处理事件 ... msg.recycle(); } }
4,步骤3中的轮询(Looper)获取到了一个消息(Message),这个Message是ActivityThread中的成员H(H是一个Handler)发来的。这个步骤获取到消息,派发消息,这个消息的处理事件就是启动一个Activity,即是调用ActivityThread中的handlerLaunchActivity()方法,辗转调用
performLaunchActivity()方法。
H是ActivityThread中的一个嵌套类,在ActivityThread的main方法中,通过IPC告诉AMS要启动一个Activity,最后调用了ActivityThread中的handlerLaunchActivity()方法
private class H extends Handler { public static final int LAUNCH_ACTIVITY = 100; ... public void handleMessage(Message msg) { ... switch (msg.what) { case LAUNCH_ACTIVITY: { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); ActivityClientRecord r = (ActivityClientRecord)msg.obj; r.packageInfo = getPackageInfoNoCheck( r.activityInfo.applicationInfo, r.compatInfo); handleLaunchActivity(r, null);//调用ActivityThread的handleLaunchActivity()方法 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } break; ... } ... }
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) { ... //主要就是这一句 Activity a = performLaunchActivity(r, customIntent); if (a != null) { ... } else { // If there was an error, for any reason, tell the activity // manager to stop us. try { ActivityManagerNative.getDefault() .finishActivity(r.token, Activity.RESULT_CANCELED, null); } catch (RemoteException ex) { // Ignore } } }
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { // System.out.println("##### [" + System.currentTimeMillis() + // "] ActivityThread.performLaunchActivity(" + r + ")"); 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); } // 准备构造Activity Activity activity = null; try { java.lang.ClassLoader cl = r.packageInfo.getClassLoader(); // 这里就是通过反射构造Activity activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent); StrictMode.incrementExpectedActivityCount(activity.getClass()); r.intent.setExtrasClassLoader(cl); if (r.state != null) { r.state.setClassLoader(cl); } } catch (Exception e) { if (!mInstrumentation.onException(activity, e)) { throw new RuntimeException("Unable to instantiate activity " + component + ": " + e.toString(), e); } } try { Application app = r.packageInfo.makeApplication(false, mInstrumentation); ... if (activity != null) { Context appContext = createBaseContextForActivity(r, activity); ... //调用Activity的attach方法 activity.attach(appContext, this, getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo, title, r.parent, r.embeddedID, r.lastNonConfigurationInstances, config); ... //调用Activity的OnCreate方法 activity.mCalled = false; mInstrumentation.callActivityOnCreate(activity, r.state); ... } r.paused = true; mActivities.put(r.token, r); } catch (SuperNotCalledException e) { throw e; } catch (Exception e) { if (!mInstrumentation.onException(activity, e)) { throw new RuntimeException("Unable to start activity " + component + ": " + e.toString(), e); } } return activity; }
5,步骤4中的performLaunchActivity()方法调用了Instrumentation的callActivityOnCreate()方法,实际上,ActivityThread并没有直接管理Activity,而是通过Instrumentation间接管理Activity,这种关系就像是,ActivityThread是一个外交官,负责与ActivityManagerService沟通,当AMS让ActivityThread启动一个Activity或者rusume一个Activity的时候,ActivityThread就告诉Instrumentation,“帮我启动某某某Activity”,然后Instrumentation就启动相应的Activity,Instrumentation负责实例化Activity并管理Activity的声明周期。
6,MainActivity的onCreate()方法。开发者重写的方法。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories