Android_WMS_启动流程

Android_WMS_启动流程,第1张

本文主要是基于android1000来讲述下WMS的启动流程

WMS作为系统的一个关键服务其是在SystemServerjava::startOtherServices中启动的

WMS主要有下面几个作用

1:应用程序通过WMS向SurfaceFinger申请surface,surface代表的是绘图表面,应用程序绘制都必须在绘图表面上

2:管理窗口的层级,一个窗口一般在WMS端都是一个WindowState,其是有层级区分的,其有baseLayer和subLayer两个值共同确定

3:窗口动画:WindowAnimator

其中上面有一个比较重要的对象PhoneWindowManager,主要是负责窗口管理的各种策略

WindowManagerPolicy mPolicy;---------------->对应的实现类PhoneWindowManager,主要是窗口管理的策略和按键的处理

final ActivityManagerInternal mAmInternal;------>对应的是AMS,持有AMS对象

final ActivityTaskManagerInternal mAtmInternal;--->管理Task的,android100新增

final ArraySet<Session> mSessions = new ArraySet<>();---->会话,主要是建立和surfaceFinger的连接

final WindowHashMap mWindowMap = new WindowHashMap();---->缓存windowstate

AMS,WMS之间数据是对应的,通过token值可以在AMS,WMS,应用程序之后来唯一确定一组Window,token是关联着一组窗口的,可能有多个WindowState的token值是相同的

整个启动过程涉及3个线程: system_server主线程, “androiddisplay”, “androidui”, 整个过程是采用阻塞方式(利用HandlerrunWithScissors)执行的 其中WindowManagerServicemH的Looper运行在 “androiddisplay”进程,也就意味着WMSHhandleMessage()在该线程执行。

在Android中启动JAVA程序其实有很多种方式,现总结如下

一、在Android应用程序中发送Intent启动Android应用程序

这个方式最简单,最常用。在此不在累述。关于Intent的更多内容请阅读《Intent技术简介》

二、在shell控制台通过am命令发送Intent来启动Android应用程序

在Android的shell控制台通过am命令发送Intent来启动Android应用程序

关于此的详细内容请参考《Android命令am详解》

三、在shell控制台直接通过davlikvm命令启动一个JAVA程序。

该方式有个天生的缺点,即在其中,很多Android的JNI无法调用。因为Android的很多JNI其实是需要手动注册的。

关于请参考《基本Dalvik VM调用》

四、在shell控制台直接通过运行app_process程序启动一个JAVA程序

在app_process程序中,他会对Android的JNI进行手动注册的,能很好的使用Android的API,因此通过运行app_process程序启动一个JAVA程序,是一个比较完美的方式。app_process程序是一个C程序,它的源码位于frameworks\base\cmds\app_process。

关于它的使用请参考《Android命令am详解》以及shell脚本frameworks\base\cmds\am\am和frameworks\base\cmds\pm\pm

am脚本文件如下:

# Script to start "am" on the device, which has a very rudimentary# shell#base=/systemexport CLASSPATH=$base/framework/amjarexec app_process $base/bin comandroidcommandsamAm "$@"pm脚本文件如下:

# Script to start "pm" on the device, which has a very rudimentary# shell#base=/systemexport CLASSPATH=$base/framework/pmjarexec app_process $base/bin comandroidcommandspmPm "$@"CLASSPATH指定了你的程序的位置,comandroidcommandspmPm则说明了程序的入口为comandroidcommandspmPm,即入口函数main()所在的类,"$@"就是传递给main()函数的参数,只是这里"$@"本身又是个shell传入的参数而已

需要注意的是CLASSPATH中的文件必须是dalvik文件格式的,关于此的转换请参考《基本Dalvik VM调用》当然CLASSPATH中的文件可以是apk文件,只是你的apk中至少应该有个拥有main()入口函数的类。

转载

其实Android启动线程和JAVA一样有两种方式,一种是直接Thread类的start方法,也就是一般写一个自己的类来继承Thread类。另外一种方式其实和这个差不多啊! 那就是Runnable接口,然后把Runnable的子类对象传递给Thread类再创建Thread对象总之都是需要创建Thread对象,然后调用Thread类的start方法启动线程。区别就是,一个是直接创建Thread对象,另外一个是需要implement了Runnable接口对象作为创建Thread对象的参数。Runnable其实我们称为线程任务。

第一种方式一般是这样用:

Class MyThread extends Thread{

public void run(){

//你要实现的代码

}

}

在主线程中启动这个线程:

public class Test{

public static void main(String[] args){

new MyThread()start();//启动了我们的线程了

}

}

2,第二种方式一般是这样用:

public class MyRunnable implements Runnable{

public void run(){

//你需要实现的代码

}

}

在主线程中启动这个线程:

public class Test{

public static void main(String[] args){

Thread t=new Thread(new MyRunnable());//这里比第一种创建线程对象多了个任务对象

tstart();

}

}

这里我想说的是可能你问这个问题是接触到了Android中的Handler概念:

其实Handler并不是开辟新线程的概念,Android主要的考虑到更新界面的问题,一般情况下,更新界面(Activity)都是在主线程中更新的,这样就遇到了一个问题,比方说:在下载文件时候我们需要进度条显示下载进度,界面需要更新(数据是不断变的,也就是下载的大小是不断变的,要是直接在主线程中更新,就会造成程序的堵塞,程序很容易崩溃,通常这样联网耗时的工作需要开辟另外一个线程的,这样就不会影响主程序了),好了,到这里联网 *** 作一般都需要开辟新线程了吧。。

接下来就来说Handler了,刚刚我说了Handler不是开辟新线程,在我看来,Handler更像是主线程的秘书,是一个触发器,负责管理从子线程中得到更新的数据,然后在主线程中更新界面。简单说下进度条的那个:

下载了多少的数据都是在子线程中得到的,在子线程中通过Handler的sendMessage()方法发送得到的下载的数据,当你调用了sendMessage方法后,Handler就会回调(也就是自动调用)Handler中的 HandlerMessage方法。

我很认真写了,希望分给我! 要是还有不懂的,可以追问,总之Handler不是开辟线程,开辟线程的方式就和JAVA一样的! 千万不要被Android中的Handler混淆。

Activity启动模式有4种,分别为standard、singleTop、singleTask、singleInstance。

1standard 默认模式,可以不用写配置。在这个模式下,都会默认创建一个新的实例。因此,在这种模式下,可以有多个相同的实例,也允许多个相同Activity叠加。

2singleTop 可以有多个实例,但是不允许多个相同Activity叠加。即,如果Activity在栈顶的时候,启动相同的Activity,不会创建新的实例,而会调用其onNewIntent方法。

3singleTask 只有一个实例。在同一个应用程序中启动他的时候,若Activity不存在,则会在当前task创建一个新的实例,若存在,则会把task中在其之上的其它Activity destory掉并调用它的onNewIntent方法。

4singleInstance只有一个实例,并且这个实例独立运行在一个task中,这个task只有这个实例,不允许有别的Activity存在。

android程序强行关闭后,让程序自动启动的方法为:

1、自己建一个service,不断的去判断,如果Activity挂掉了,就在service里启动它。

2、在程序里面写个广播什么的到程序里面 ,比如 一些apk程序。一检测到wifi开启,广播就激发,启动程序。

Android系统的Home应用程序Launcher是由ActivityManagerService启动的,而ActivityManagerService和PackageManagerService一样,都是在开机时由SystemServer组件启动的,SystemServer组件首先是启动ePackageManagerServic,由它来负责安装系统的应用程序,具体可以参考前面一篇文章Android应用程序安装过程源代码分析,系统中的应用程序安装好了以后,SystemServer组件接下来就要通过ActivityManagerService来启动Home应用程序Launcher了,Launcher在启动的时候便会通过PackageManagerServic把系统中已经安装好的应用程序以快捷图标的形式展示在桌面上,这样用户就可以使用这些应用程序了,整个过程如下图所示:

      下面详细分析每一个步骤。

     Step 1 SystemServermain

     这个函数定义在frameworks/base/services/java/com/android/server/SystemServerjava文件中,具体可以参考前面一篇文章Android应用程序安装过程源代码分析的Step 1。

     Step 2 SystemServerinit1

     这个函数是一个JNI方法,实现在 frameworks/base/services/jni/com_android_server_SystemServercpp文件中,具体可以参考前面一篇文章Android应用程序安装过程源代码分析的Step 2。

     Step 3 libsystem_serversystem_init

     函数system_init实现在libsystem_server库中,源代码位于frameworks/base/cmds/system_server/library/system_initcpp文件中,具体可以参考前面一篇文章Android应用程序安装过程源代码分析的Step 3。

     Step 4 AndroidRuntimecallStatic

     这个函数定义在frameworks/base/core/jni/AndroidRuntimecpp文件中,具体可以参考前面一篇文章Android应用程序安装过程源代码分析的Step 4。

     Step 5 SystemServerinit2

     这个函数定义在frameworks/base/services/java/com/android/server/SystemServerjava文件中,具体可以参考前面一篇文章Android应用程序安装过程源代码分析的Step 5。

     Step 6 ServerThreadrun

     这个函数定义在frameworks/base/services/java/com/android/server/SystemServerjava文件中,具体可以参考前面一篇文章Android应用程序安装过程源代码分析的Step 6。

     Step 7 ActivityManagerServicemain

     这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerServciejava文件中:

[java] view plaincopy

public final class ActivityManagerService extends ActivityManagerNative

implements WatchdogMonitor, BatteryStatsImplBatteryCallback {

public static final Context main(int factoryTest) {

AThread thr = new AThread();

thrstart();

synchronized (thr) {

while (thrmService == null) {

try {

thrwait();

} catch (InterruptedException e) {

}

}

}

ActivityManagerService m = thrmService;

mSelf = m;

ActivityThread at = ActivityThreadsystemMain();

mSystemThread = at;

Context context = atgetSystemContext();

mmContext = context;

mmFactoryTest = factoryTest;

mmMainStack = new ActivityStack(m, context, true);

mmBatteryStatsServicepublish(context);

mmUsageStatsServicepublish(context);

synchronized (thr) {

thrmReady = true;

thrnotifyAll();

}

mstartRunning(null, null, null, null);

return context;

}

}

     这个函数首先通过AThread线程对象来内部创建了一个ActivityManagerService实例,然后将这个实例保存其成员变量mService中,接着又把这个ActivityManagerService实例保存在ActivityManagerService类的静态成员变量mSelf中,最后初始化其它成员变量,就结束了。

     Step 8 PackageManagerServicemain

     这个函数定义在frameworks/base/services/java/com/android/server/PackageManagerServicejava文件中,具体可以参考前面一篇文章Android应用程序安装过程源代码分析的Step 7。执行完这一步之后,系统中的应用程序的所有信息都保存在PackageManagerService中了,后面Home应用程序Launcher启动起来后,就会把PackageManagerService中的应用程序信息取出来,然后以快捷图标的形式展示在桌面上,后面我们将会看到这个过程。

以上就是关于Android_WMS_启动流程全部的内容,包括:Android_WMS_启动流程、如何在Android中启动JAVA程序、Android里有哪些方法启动线程等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/10104636.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-05
下一篇 2023-05-05

发表评论

登录后才能评论

评论列表(0条)

保存