Android程序的入口到底在哪里呢?任何的控制类程序都有一个入口,而Android基于java语言的,因此java程序的入口必须在某一个类的静态成员函数main();而在Android程序main函数在类ActivityThread中,看看ActivityThread.main()做了什么?
public final class ActivityThread {
......
public static void main(String[] args) {
.....
Looper.prepareMainLooper();//创建MessageQueue消息队列
ActivityThread thread = new ActivityThread();//创建ActivityThread对象
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();//获取Handler对象
}
......
}
final ApplicationThread mAppThread = new ApplicationThread();
final Looper mLooper = Looper.myLooper();
final H mH = new H()
}
程序首先在ActivityThread类main()函数执行,调用函数prepareMainLooper()在主线程创建一个消息队列(MessageQueue)。
然后创建ActivityThread对象,在ActivityThread对象创建的同时,创建ApplicationThread对象,和Handler对象。
ApplicationThread对象作用:ApplicationThread对象是Binder对象,负责接收远程的AMS的IPC调用。
Handler对象作用: 负责发送消息到消息队列。UI线程会异步的从消息队列取出消息并做相应的操作。
当有了这两个对象后,就可以接收AMS发送来的远程消息(start,stop,pause)。并且可以回调回ActivityThread
当ApplicationThread对象接收到AMS发送start某个 Activity,通过Handler发送消息到消息队列,ActivityThread.handleMessage取出相应的消息,就会创建指定的Activity。Activity是怎样被创建出来的?去看看ActivityThread.handleMessage做了什么?
public final class ActivityThread {
......
public void handleMessage(Message msg) {
switch (msg.what) {
case LAUNCH_ACTIVITY: {
......
handleLaunchActivity(r, null);
......
break;
}
}
}
}
当AMS要start某个Activity,回调到ActivityThread.handleMessage中,调用handleLaunchActivity函数。进入handleLaunchActivity函数看看。
public final class ActivityThread {
......
Activity a = performLaunchActivity(r, customIntent);
......
if (a != null) {
......
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed);
......
}
.......
}
}
进去一看调用了performLaunchActivity函数返回Activity,想必在这个函数中创建Activity的,再去看看performLaunchActivity函数。
public final class ActivityThread {
......
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
......
Activity activity = null;
......
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
......
return activity;
}
}
在performLaunchActivity函数可以看出,通过类加载器在mInstrumentation.newActivity函数中创建出Activity。就这样Activity就创建出来了。
(1)当Activity被创建出来后,又会创建相关的类,创建的流程为:
contextImpl类–>PhoneWindow类——->WindowManagerImpl类—->DecorView类—->相应的VIew后ViewGroup(layout.xml布局文件)。
创建完后,Activity需要把创建好的界面显示到屏幕上,调用的流程为:
WindowManager类—->ViewRoot类—->WMS远程接口,这样就完成一个窗口添加到屏幕上。
由(1)可以得出Android应用程序窗口的大概模型:
当窗口添加到屏幕上后接下来,用户开始在程序界面上操作,KeyQ线程把这些消息保存到消息队列中,而InputDipatchThread线程逐个的取出消息,然后调用WMS的相应消息处理函数,WMS判断该消息是属于哪一个窗口的,然后封装好,发送给相应的ViewRoot中的W接口。
事件分发的过程:
WMS—–>ViewRoot.W接口—->ViewRoot类—>ActivityThread —->PhoneWindon.DecorView—->Activity—–>PhoneWindow—->PhoneWIndow.Decorview—>ViewGroup—->子view。
由上面流程可知,app程序运行的大概的整体流程可总结为两点:
创建窗口(UI)显示在屏幕上。—–>a
接收用户消息(按键,触摸) 发给相应的窗口做相应的处理。—->b
对于a:创建Activity对象之后会继续创建ContextImpl类,PhoneWindow类,DecorView类,WindowManagerImpl类,ViewRoot类,layout.xml(布局文件),接下来的文章会根据源码分析这些对象的产生和这些类的继承关系,类的作用,这些类之间的关系。
由(1)得出Android应用程序窗口模型,换种理解:
Android应用程序窗口 = Activity + PhoneWindow + DecorView;—->c
DecorView = TitleView + contentView(layout.xml布局文件);—–>d
这里的等于号并不是真正意思的等于,这里描述的是一种大概的意思,对于c而言,Android应用程序窗口模型 描述为,大概 由Activity + PhoneWindow +DecorView组成,而DecorView 大概由TitleView + ContentView(layout.xml布局文件)组成。只是大概的由这些组成。Android应用程序窗口的组成 还可以 包括 Dialog, PopupWIndow。
而d 就是我们要学习的重点,简称Android应用程序窗口视图;添加窗口到屏幕上,其实最重要的就是把我们的布局文件绘制上去,而这就是我们常说的View的绘制。
经过这样分析,又可以把app程序运行过程的两个重要点可以总结为:
View的绘制;
用户消息事件的分发:
这里出现了几个很重要的类,AMS,WMS,WM,ViewRoot,Activity,ActivityThread,它们之间的关系:
整个流程可以总结为: