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