在一个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 ) {
.....
}
}
|
这也解释了为啥在主线程里面不能做耗时操作,即主线程不能被占用,因为主线程里面有个消息循环在转
时间: 2024-11-05 18:30:46