FrameWork的概述与启动过程

news2024/9/20 20:44:18

FrameWork框架

Framework定义了客户端组件和服务端组件功能及接口。以下阐述中,“应用程序”一般是指“.apk”程序。

框架中包含三个主要部分,分别为服务端、客户端和Linux驱动。

服务端

服务端主要包含两个重要类,分别是WindowManagerService(WmS)和ActivityManagerService
(AmS)。

WmS的作用是为所有的应用程序分配窗口,并管理这些窗口。包括分配窗口的大小,调节各窗口的叠放次序,隐藏或者显示窗口。

AmS的作用是管理所有应用程序中的Activity。

除此之外,在服务端还包括两个消息处理类。

KeyQ类:该类为WmS的内部类,继承于KeyInputQueue类,KeyQ对象一旦创建,就立即启动一个线程,该线程会不断地读取用户的UI操作消息,比如按键、触摸屏、trackball、鼠标等,并把这些消息放到一个消息队列QueueEvent类中。

InputDispatcherThread类:该类的对象一旦创建,也会立即启动一个线程,该线程会不断地从QueueEvent中取出用户消息,并进行一定的过滤,过滤后,再将这些消息发送给当前活动的客户端程序中。

客户端

客户端主要包括以下重要类。

  • ActivityThread类:该类为应用程序的主线程类,所有的APK程序都有且仅有一个ActivityThread类,程序的入口为该类中的static main()函数。

  • Activity类:该类为APK程序的一个最小运行单元,一个APK程序中可以包含多个Activity对象,ActivityThread主类会根据用户操作选择运行哪个Activity对象。

  • PhoneWindow类:该类继承于Window类,同时,PhoneWindow类内部包含了一个DecorView对象。简而言之,PhoneWindow是把一个FrameLayout进行了一定的包装,并提供了一组通用的窗口操作接口。

  • Window类:该类提供了一组通用的窗口(Window)操作API,这里的窗口仅仅是程序层面上的,WmS所管理的窗口并不是Window类,而是一个View或者ViewGroup类,一般就是指DecorView类,即一个DecorView就是WmS所管理的一个窗口。Window是一个abstract类型。

  • DecorView类:该类是一个FrameLayout的子类,并且是PhoneWindow中的一个内部类。Decor的英文是Decoration,即“修饰”的意思,DecorView就是对普通的FrameLayout进行了一定的修饰,比如添加一个通用的Title bar,并响应特定的按键消息等。

  • ViewRoot类:WmS管理客户端窗口时,需要通知客户端进行某种操作,这些都是通过异步消息完成的,实现的方式就是使用Handler,ViewRoot就是继承于Handler,其作用主要是接收WmS的通知。

  • W类:该类继承于Binder,并且是ViewRoot的一个内部类。

  • WindowManager类:客户端要申请创建一个窗口,而具体创建窗口的任务是由WmS完成的,WindowManager类就像是一个部门经理,谁有什么需求就告诉它,由它和WmS进行交互,客户端不能直接和WmS进行交互。

Linux驱动

Linux驱动和Framework相关的主要包含两部分,分别是SurfaceFlingger(SF)和Binder。每一个窗口都对应一个Surface,SF驱动的作用是把各个Surface显示在同一个屏幕上。

Binder驱动的作用是提供跨进程的消息传递。

APK程序的运行过程

public static final void main(String[] args) {
        SamplingProfilerIntegration.start();
 
        Process.setArgV0("<pre-initialized>");
 
        Looper.prepareMainLooper();
        if (sMainThreadHandler == null) {
            sMainThreadHandler = new Handler();
        }
 
        ActivityThread thread = new ActivityThread();
        thread.attach(false);
 
        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }
 
        Looper.loop();
 
        if (Process.supportsProcesses()) {
            throw new RuntimeException("Main thread loop unexpectedly exited");
        }
 
        thread.detach();
        String name = (thread.mInitialApplication != null)
            ? thread.mInitialApplication.getPackageName()
            : "<unknown>";
        Slog.i(TAG, "Main thread of " + name + " is now exiting");
    }

首先,ActivityThreadmain()函数中开始执行,调用prepareMainLooper()为UI线程创建一个消息队列(MessageQueue)。

然后创建一个ActivityThread对象,在ActivityThread的初始化代码中会创建一个H(Handler)对象和一个ApplicationThread(Binder)对象。

其中Binder负责接收远程AmS的IPC调用,接收到调用后,则通过Handler把消息发送到消息队列,UI主线程会异步地从消息队列中取出消息并执行相应操作,比如start、stop、pause等。

    final ApplicationThread mAppThread = new ApplicationThread();
    final H mH = new H();

接着UI主线程调用Looper.loop()方法进入消息循环体,进入后就会不断地从消息队列中读取并处理消息。

ActivityThread接收到AmS发送start某个Activity后,就会创建指定的Activity对象。Activity又会创建PhoneWindow类→DecorView类→创建相应的View或者ViewGroup。

创建完成后,Activity需要把创建好的界面显示到屏幕上,于是调用WindowManager类,后者于是创建一个ViewRoot对象,该对象实际上创建了ViewRoot类和W,创建ViewRoot对象后,WindowManager再调用WmS提供的远程接口完成添加一个窗口并显示到屏幕上。

接下来,用户开始在程序界面上操作。KeyQ线程不断把用户消息存储到QueueEvent队列中,InputDispatcherThread线程逐个取出消息,然后调用WMS中的相应函数处理该消息。当WMS发现该消息属于客户端某个窗口时,就会调用相应窗口的W接口。

W类是一个Binder,负责接收WmS的IPC调用,并把调用消息传递给ViewRoot,ViewRoot再把消息传递给UI主线程ActivityThread,ActivityThread解析该消息并做相应的处理。

在客户端程序中,首先处理消息的是DecorView,如果DecorView不想处理某个消息,则可以将该消息传递给其内部包含的子View或者ViewGroup,如果还没有处理,则传递给PhoneWindow,最后再传递给Activity。

客户端中的线程

在多任务操作系统中,任何程序都运行在线程之中。系统首先会为客户端程序分配一个线程,然后该线程从程序的入口处开始执行。那么,请思考以下问题。

启动Android APK 时 程序中都有哪些线程?

首先,很明确地讲,包含有Activity的客户端程序至少包含三个线程。每个Binder对象都对应一个线程,Activity启动后会创建一个ViewRoot.W对象,同时ActivityThread会创建一个ApplicationThread对象,这两个对象都继承于Binder,因此会启动两个线程,负责接收Linux Binder驱动发送IPC调用。最后一个主要线程也就是程序本身所在的线程,也叫做用户交互(UI)线程,因为所有的处理用户消息,以及绘制界面的工作都在该线程中完成。

private final class ApplicationThread extends ApplicationThreadNative { ... }
public abstract class ApplicationThreadNative extends Binder
        implements IApplicationThread { ... }
static class W extends IWindow.Stub { ... }

为了验证这一点,可以在Eclipse中新建一个Hello Android的程序,然后以debug的方式运行,在debug窗口中会看到如图所示的界面。
在这里插入图片描述

窗口相关的概念

在源码中,会经常提到以下概念,窗口、Window类、ViewRoot类以及W类,简单介绍这些概念的联系和区别。

  • 窗口(不是指的Window类):这是一个纯语义的说法,即程序员所看到的屏幕上的某个独立的界面,比如一个带有Title Bar的Activity界面、一个对话框、一个Menu菜单等,这些都称之为窗口。本书中所说的窗口管理一般也都泛指所有这些窗口,在Android的英文相关文章中则直接使用Window这个单词。而从WmS的角度来讲,窗口是接收用户消息的最小单元,WmS内部用特定的类表示一个窗口,以实现对窗口的管理。WmS接收到用户消息后,首先要判断这个消息属于哪个窗口,然后通过IPC调用把这个消息传递给客户端的ViewRoot类。

  • Window类:该类在android.view包中,是一个abstract类,该类抽象了“客户端窗口”的基本操作,并且定义了一组Callback接口,Activity类就是通过实现这个Callback接口以获得对消息处理的机会,因为消息最初是由WmS传递给View对象的。

  • ViewRoot类:该类在android.view包中,客户端申请创建窗口时需要一个客户端代理,用以和WmS进行交互,ViewRoot内部类W就是完成这个功能的。WmS所管理的每一个窗口都会对应一个ViewRoot类。

  • W类:该类是ViewRoot类的一个内部类,继承于Binder,用于向WmS提供一个IPC接口,从而让WmS控制窗口客户端的行为。

描述一个窗口之所以使用这么多类的原因在于,窗口的概念存在于客户端和服务端(WmS)之中,并且Framework又定义了一个Window类,这很容易让人产生混淆,实际上WmS所管理的窗口和Window类没有任何关系。

Framework(Android)的启动过程

Android启动过程包含从Linux内核加载到Home应用程序启动的整个过程。

  • 1)Android是基于linux内核的系统平台,启动时,首先通过Bootloader(系统加载器),加载Linux内核。在Linux加载启动时,与普通的Linux启动过程相同,先初始化内核,然后调用init进程(Linux用户空间中第一个进程,是所有进程的父进程)。

  • 2) Init进程启动Zygote。init进程启动. init进程主要来创建和挂载启动所需的文件目录,启动属性服务(类似于windows的注册表),启动Zygote进程。

  • 3) Zygote(孵化器)进程的建立是真正的Android运行空间,Zygote孵化第一个进程SystemServer,SystemServer启动各种系统服务线程。

SystemServer进程在Android的运行环境中扮演了"神经中枢"的作用,APK应用中能够直接交互的大部分系统服务都在该进程中运行,常见的比如WindowManagerServer(WMS)、ActivityManagerSystemService(AMS)、PackageManagerServer(PMS)等,这些系统服务都是以一个线程的方式存在于SystemServer进程中。

SystemService会启动Binder线程池 创建SystemServiceManage对系统服务的创建启动和生命周期进程管理,并启动各种java层系统服务,接着会调用WMS,AMS等服务的systemReady()完成启动.

  • 4) 当以上服务线程都启动后,AMS以systemReady调用完成最后启动,在ActivityManagerServicesystemReady方法中调用startHomeActivityLocked来启动ActionIntent.ACTION_MAINCategoryIntent.CATEGORY_HOME的应用,也就是Launcher所配置的标签,启动第一个Activity。至此,Android系统的启动完成。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/959950.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

jsch网页版ssh

使用依赖 implementation com.jcraft:jsch:0.1.55Server端代码 import com.jcraft.jsch.Channel; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import java.io.InputStream; import java.io.OutputStream; import java.util.concurrent.TimeUnit; import o…

django项目改名字后顺利运行、ModelSerializer使用、模块与包的使用、反序列化校验源码分析、断言、drf之请求、魔法方法之点(.)拦截

一 django项目改名字后顺利运行 1 先改文件夹名 2 改项目名 3 改 项目内的文件夹名 4 替换掉所有文件中的 drf_day04_02 ---》drf_day05 5 命令行中启动&#xff1a;python manage.py runserver 6 setting--->django--->指定项目根路径二 同时创建作者和作者详情表(一对…

Ros noetic 机器人坐标记录运动路径和发布 实战教程(A)

前言: 网上记录Path的写入文件看了一下还挺多的,有用yaml作为载体文件,也有用csv文件的路径信息,也有用txt来记录当前生成的路径信息,载体不重要,反正都是记录的方式,本文主要按yaml的方式写入,后文中将补全其余两种方式。 其中两种方式的主要区别在于,加载yaml所需要…

ASUS华硕VivoBook15笔记本V5200EA_X515EA原装出厂Win11预装OEM系统

华硕11代酷睿笔记本电脑VivoBook_ASUSLaptop X515EA_V5200EA原厂Windows11系统 自带显卡、声卡、网卡、蓝牙等所有驱动、出厂主题壁纸、Office办公软件、华硕电脑管家MyASUS、迈克菲等预装程序 链接&#xff1a;https://pan.baidu.com/s/1yAEdA7aiuHK4CTdGLlSOKw?pwdo45a …

【MySQL】一文带你搞懂MySQL中的各种锁

1.概述 锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中&#xff0c;除传统的计算资&#xff08; CPU 、 RAM、 I/O &#xff09;的争用以外&#xff0c;数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致 性、有 效性是所有数据库必须解决的一个…

posexplode函数实战总结

目录 1、建表和准备数据 2、炸裂实践 3、错误炸裂方式 4、当字段类型为string&#xff0c;需要split一下 对单列array类型的字段进行炸裂时&#xff0c;可以使用lateral view explode。 对多列array类型的字段进行炸裂时&#xff0c;可以使用lateral view posexplode。 1…

命令行编译VS工程

先输入以下命令&#xff0c;因为命令出错了&#xff0c;就会弹出帮助&#xff0c;如下&#xff1a; "C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\devenv.exe" /help 反正就是Microsoft Visual Studio 的安装路径。 帮助界面如下&#xff1a…

新风机为什么会出现?

新风机之所以会出现&#xff0c;是因为人们对于室内空气质量的重视与需求。随着社会的进步和人们生活水平的提高&#xff0c;人们更加注重健康和舒适的居住环境&#xff0c;而室内空气质量是其中一个重要的方面。 空气污染问题&#xff1a;城市化进程加速&#xff0c;工业排放、…

vue3+ts+uniapp小程序端自定义日期选择器基于内置组件picker-view + 扩展组件 Popup 实现自定义日期选择及其他单列选择

vue3ts 基于内置组件picker-view 扩展组件 Popup 实现自定义日期选择及单列选择 vue3tsuniapp小程序端自定义日期选择器 1.先上效果图2.代码展示2.1 组件2.2 公共方法处理日期2.3 使用组件(全局自动导入的情况) 3.注意事项3.1refSelectDialog3.1 backgroundColor"#fff&q…

Python做数据分析更快,为什么很多人只学Excel,不学Python?

在当今信息时代&#xff0c;数据分析已经成为了各个行业不可或缺的工作内容。而在数据分析中&#xff0c;Excel一直是最常被使用的工具之一。然而&#xff0c;随着Python编程的兴起&#xff0c;越来越多的数据分析师开始转向Python进行数据分析。本文将从速度、灵活性、可视化和…

跳转语句(个人学习笔记黑马学习)

break语句 #include <iostream> using namespace std;int main() {cout << "请选择副本难度" << endl;cout << "1、普通" << endl;cout << "2、中等" << endl;cout << "3、困难" <…

gRPC-GateWay Swagger 实战

上一次我们分享了关于 gRPC-Gateway 快速实战 &#xff0c;可以查看地址来进行回顾 : 也可以查看关于 gRPC 的历史文章&#xff1a; gRPC介绍 gRPC 客户端调用服务端需要连接池吗&#xff1f; gRPC的拦截器 gRPC的认证 分享一下 gRPC- HTTP网关 I 今天主要是分享关于 gRPC-G…

zabbix安装部署

前期准备&#xff1a;安装mysql数据库和nginx 一、下载zabbix rpm -Uvh https://repo.zabbix.com/zabbix/4.4/rhel/7/x86_64/zabbix-release-4.4-1.el7.noarch.rpm yum-config-manager --enable rhel-7-server-optional-rpms yum install epel-release numactl yum install…

洞察商机,驱动创新:智能数据分析引领企业发展

“五度易链”产业大数据解决方案由产业经济、智慧招商、企业服务、数据服务四大应用解决方案组成&#xff0c;囊括了产业经济监测、产业诊断分析、企业监测预警、企业综合评估、大数据精准招商、招商智能管理、企业管理、企业培育、企业市场服务、企业金融服务、产业数据开放服…

Layer 2盛夏已至,StarkNet如何实现价值跃迁?

作者&#xff5c;Jason Jiang Layer 2概念在2023年夏天迎来爆发。Coinbase、ConsenSys等加密巨头纷纷下场&#xff0c;其部署的原生L2解决方案Base、Linea在过去两个月内相继完成主网上线&#xff1b;被誉为L2 四大天王之一的StarkNet也在夏天顺利完成“量子跃迁”升级&#x…

SQL优化案例教程0基础(小白必看)

前提准备&#xff1a;本案例准备了100W的数据进行SQL性能测试&#xff0c;数据库采用的是MySQL&#xff0c; 总共介绍了常见的14种SQL优化方式&#xff0c;每一种优化方式都进行了实打实的测试&#xff0c; 逐行讲解&#xff0c;通俗易懂&#xff01; 一、前提准备 提前准备一…

Sqoop实操案例-互联网招聘数据迁移

&#x1f947;&#x1f947;【大数据学习记录篇】-持续更新中~&#x1f947;&#x1f947; 个人主页&#xff1a;beixi 本文章收录于专栏&#xff08;点击传送&#xff09;&#xff1a;【大数据学习】 &#x1f493;&#x1f493;持续更新中&#xff0c;感谢各位前辈朋友们支持…

mybatis plus 3.4以上分页无效问题,limit一直加不上,MybatisPlusInterceptor无效

解决方案 1、已注册 Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor new MybatisPlusInterceptor();PaginationInnerInterceptor paginationInnerInterceptor new PaginationInnerInterceptor(DbType.MYSQL);paginationIn…

idea全局搜索失效,Ctrl+shift+F快捷键不起作用

方法1&#xff1a;是否与搜狗等输入法软件存在快捷键冲突&#xff0c;当然也可能是你新下载的什么软件导致的快捷键冲突导致IDEA全局搜索失效。比如下图&#xff1a; 可以改掉输入法的快捷键或者直接关闭输入法的快捷键&#xff0c;这样idea的全局搜索功能就恢复了。 方法2&…

一文掌握光模块知识,成为网络工程师的必备技能

在这个信息爆炸的时代&#xff0c;数据传输已经成为我们生活中不可或缺的一部分。而在众多的数据传输方式中&#xff0c;光纤通信以其高速、高带宽、低损耗的特点&#xff0c;成为了现代通信的主流。而在这个光纤通信的背后&#xff0c;有一个神奇的器件在默默地发挥着作用&…