在一个Lancher里面我们点击一个快捷键图表,Android系统做了什么?
我们先看Lancher.java中的源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | public final class Launcher extends Activity{ //onCick事件 public void onClick(View v) { Object tag = v.getTag(); if (tag instanceof ApplicationInfo) { // 打开快捷键 final Intent intent = ((ApplicationInfo) tag).intent; int [] pos = new int [ 2 ]; v.getLocationOnScreen(pos); intent.setSourceBounds( new Rect(pos[ 0 ], pos[ 1 ], pos[ 0 ] + v.getWidth(), pos[ 1 ] + v.getHeight())); //重点就是这个方法 this .startActivitySafely(intent); } else if (tag instanceof FolderInfo) { this .handleFolderClick((FolderInfo) tag); } } //这个方法做了2件事 void startActivitySafely(Intent intent) { //区别于默认优先启动在activity栈中已经存在的activity //如果之前启动过,并还没有被destroy的话 //而是无论是否存在,都重新启动新的activity intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); this .startActivity(intent); } } |
通过上述代码 我们知道 有Lancher最后一步是startActivity( ),那我们继续看Activity的源码:
1 2 3 4 5 6 7 8 9 | public void startActivity(Intent intent, Bundle options) { //-1标示不需要这个Activity结束后返回结果 startActivityForResult(intent, - 1 ); } public void startActivityForResult(Intent intent, int requestCode, Bundle options) { //Instrumentation监视应用程序和系统的交互 Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(..... } |
我们走到这一步,返现一个我们不熟悉的类Instrumentation.java
1 2 3 4 5 6 7 8 | public class Instrumentation { //内部类,从类名我们知道是Activity的监视类 public static class ActivityMonitor { } //还有一些call方法,如下截图 } |
我们继续看这个类,既然它是Activity的监听类,.我们看看
1 2 3 4 5 6 7 | public Activity newActivity(...){ //通过反射构造出Activity对象 Activity activity = (Activity)clazz.newInstance(); //按照我们的习惯,应该下一步是调用Activity.onCreate(),但是趋势attach() activity.attach(context, aThread,....); //初始化Activity,生成一个window对象,设置各种状态等等 return activity; } |
ok,接下来从Instrumentation继续startActivity----------->创建任务栈AndroidStack,
一旦目标的任务栈就位,做了如下动作:
1,AndroidStack发消息给Lanucher的ActivityThread告诉Lanucher进入onPause阶段详细步骤:AndroidStack发送消息给ActivityThread<Launcher应用的主线程>线程去OnPauser掉Lancher2,AndroidStack发消息给目标应用的ActivityThread, 目标应用该启动起来了
流程图如下:
Android 手机上的应用一般情况下都在一个进程中运行,那一个进程的标示就是ActivityThread.
下面我们看一下 ActivityThread.java中的main()源码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public static final void main(String[] args) { SamplingProfilerIntegration.start(); …… Looper.prepareMainLooper(); if (sMainThreadHandler == null ) { sMainThreadHandler = new Handler(); } ActivityThread thread = new ActivityThread(); thread.attach( false ); …… Looper.loop(); //主线程while(true)? 分发消息 …… thread.detach(); …… Slog.i(TAG, "Main thread of " + name + " is now exiting" ); } |
我们接着看一下Looper.loop( ); 里面是个死循环,即在主线程有个永真循环
1 2 3 4 5 6 7 | public static final void loop() { Looper me = myLooper(); MessageQueue queue = me.mQueue; while ( true ) { ..... } } |
这也解释了为啥在主线程里面不能做耗时操作,即主线程不能被占用,因为主线程里面有个消息循环在转