首页 > 代码库 > Android系统启动-->应用启动-->界面的展示(二)

Android系统启动-->应用启动-->界面的展示(二)

在一个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掉Lancher
2,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) {
        .....
    }
}

这也解释了为啥在主线程里面不能做耗时操作,即主线程不能被占用,因为主线程里面有个消息循环在转





Android系统启动-->应用启动-->界面的展示(二)