赞
踩
本文来自刘兆贤的博客_CSDN博客-Java高级,Android旅行,Android基础领域博主 ,引用必须注明出处!
关于Framework,就是应用层底下的控制层,离应用层最近,总想找个机会,写写WindowMangerService和ActivityManagerService(注意非控件,而是指一类服务)以及其他一些东西,对底层做一个更为全面的认识。而很早以前,写过一篇文章,来简述Android系统-" Android高级之系统介绍",同样今天我们在讲Framework层时也会再对系统做一个回顾;下图是我对本节内容的一个基本介绍。
PS:W类是ViewRoot的一个内部类,ViewRoot最大作用就是把IPC调用转为本地调用。
HistoryRecord-每个Acitivty都会有一个,用来管理和记录Activity,是一个Binder对象
ViewRoot-实现View和WindowManger之间的协议,是View Hierarchy的最顶层
PhoneWindow-其中有autoManger和keyguardManager的实现对象
一、窗口
就着上图,我们会对每一条做进一步的解说(注意上图大多是包含关系,少数是关联关系,请区别对待),上图对Framework简单做了描述;同时科普一下什么叫窗口,窗口非指window类,而是指所有使用windowmanger将
其展示在用户面前的控件,如toast、activity、menu等,而这些界面通过设置window的callback来监听到wms传给view对象的信息,如手势操作。而窗口类型基本可以分为3种:
1、系统窗口,不需要父窗口-可以指定2000-2999层
2、子窗口,依赖父窗口-1000-1999层 如Toast
3、应用窗口,对应activity-小于99层 如Activity
窗口可以说是View,而wms不直接跟view沟通,而是通过实现IWindow的ViewRoot.W类,然后再传给view。
关于Context,上下文引用,项目中使用的还比较多,是一个场景,用来配合上下文操作;一个应用中context的数量=service个数+activity个数+application个数,原因它们都继承自ContextWraper,而它继承自context。
二、linux文件系统
由于android系统基于linux,就先讲一下linux基础,文件系统通常有3个特点:
1、由文件和目录组成,占据一定存储空间
2、具有读、写、执行权限,可以复制和移动
3、多个文件系统可以并列,且类型可以不同,如FAT16和NTFS
主要的文件目录有以下几种-与android系统类比:
1、bin,存放用户级二进制工具-相当于android系统的acct目录
2、boot,内核镜像文件,由bootloader装载-firmware
3、dev,各种文件系统如打印机等-相当于android系统的dev目录+storage+mnt/sdcard
4、etc,配置文件区-相当于android系统的config目录
5、home,用户工作目录-data/user
6、lib,系统运行时库的存放地-data/app-lib
7、opt,存放系统程序-data/app-private
8、proc,系统级如内核和进程所在文件-proc目录
9、root,管理员工作目录-root目录
10、sbin,管理员的二进制工具-sbin目录
11、sys,驱动对应的系统文件如固件、内核、电量等-sys目录+system目录
12、usr,应用程序安装区-data/app
13、var,调试信息等-data/anr等
因此从上面来以看出,其实操作系统都是由文件组成,外加一些硬件感应设备。但上面介绍的依然不全面,因为android是一层套一层,资源是总体一致,大体分散的结构。同时上面会涉及到进程pid,值为100以内是系统进程,1000以内是root进程,1000以上是用户进程。讲完目录,咱们再讲讲命令:
1、man,查询某命令的意思
2、ls,列出当前目录下所有文件及文件夹信息
3、find,用名字查找文件信息
4、grep,查询文件中的字符串信息
5、cat,打开文件
6、chmod,指定权限,ugo指user(自身)、group(组)、other(其他),权限有r(读1)w(写2)x(执行4),指定权限有两种方式如chmod ug+x(给予当前用户和某群组执行的权限),chmod 777(给予三者所有权限,原因请看上一行)
7、ps和kill,ps列出当前所有进程,kill杀死某进程
8、export,用于设置变量作用于全局
9、mount和unmount,加载和卸载文件系统
好在用过linux操作系统工作过一段时间,对后来做Android开发,起到很大的帮助,上面介绍的是一些常用命令,有兴趣的可以安装一个linux系统来用,之前有一个同事使用ubuntu来编译so,而我当年用的是小红帽rethat。
三、linux启动过程
下面简单讲一个linux启动过程,其实Dalvik虚拟机也是类似
上图少说一点,在CPU运行之前,要把磁盘和其他内存启动,这样才能保证系统正式开始,因为所有系统均为文件,加载文件的硬盘不启,系统如何能被启动?
四、异步信息系统
在Android系统中,用的最多的设计模式就是handler+looper+messageQueue,无论在系统层还是在应用层,
之后我们会再讲到都被用烂了,异步线程表现为:开启后无限循环,遍历数据,如果为空则等待,直到下次数据不
为空时,使用场景有二
1、任务要常驻
2、任务需要根据消息来做不同操作
使用方法如上,解释几点,上面的数据指messegeQueue属于队列LILO,读/写数据时会加锁;如何应用呢,
Handler handler =new Handler(); 首先创建handler时,一般需要在UI线程中(一般你也没必要在子线程重写
handler),获得一个UI线程的looper对象;looper对象通过prepare方法(仅一次)准备一个MessageQueue
(系统唯一),调用loop方法一直分发消息;MessageQueue可以定义消息处理时刻,否则先进先出,
通过next和enquenceMessage方法来取和加入消息,处于wait状态则唤醒,若无消息则挂起。
五、Binder
再讲一个知识点Binder,然后结束本篇。
Binder工作在linux层面,是一小段内存,属于驱动,主要用来解决IPC调用,应用框架包括3部分
1、服务端接口-Binder对象,收到消息即启动隐藏线程,执行onTransact函数初始化;向客户端发送消息时,
挂起当前线程。
2、Binder驱动-创造mRemote的Binder对象,重载以下方法
1)以线程间消息通信模式,向服务端发送参数
2)挂起客户端线程,等待服务端返回处理结果,并通知客户端
3)接收服务端通知,继续执行客户端线程
3、客户端接口-向客户端发送消息,挂起当前线程。
Binder服务的设计原则是,开放ServiceManger接口给外界,关于具体的操作由底层去统一执行,不暴露出来,
这也是保证框架稳定、逻辑正确的重要方式,使不同管理类与底层实现可以分离解耦。
另一篇关于Binder介绍,最下面:Android源码剖析之Framwork层消息传递(Wms到View)_刘兆贤的博客-CSDN博客
下面这篇文章底层就是使用binder进行通信
六、token
token原意指口令,在这里指“身份证”,代表唯一性和代理性;一般token为IBind的实现类,即使View.Attach
Info中也是用IBind实现类来进行IPC调用。应用窗口一般都有token,而window可能没有,为什么?window可以不
对应此窗口存在。
应用窗口的token:一般最初跟window一样最终指向DecorView的W类,初始值是window的mAppToken,指应用
HistoryRecord。Activity的token起始是HistoryRecord,最终指向此W类即mAppToken,与window相同。
子窗口的token:是父窗口view的W类,即mPanelParentWindowToken
系统窗口无token
因此view中会有window的token,也会有父窗口的token,而每个应用窗口随activity诞生,均会有一个Activity
Thread陪伴。
Android的安装过程:Android内核解读-应用的安装过程 - Android移动开发技术文章_手机开发 - 红黑联盟
Binder能支持跨进程通信的原因,是它实现IBinder接口,系统定义实现此接口即赋予进程通信的功能。
Binder通信协议包含两部分:
Binder_Command_Protocal,简称BC,负责将数据从IPC层传递后Binder Driver层。
Binder_Return_Protocal,简单称BR,负责将数据从Binder Driver层传递到IPC调用层。
优势:做数据拷贝只用1次,则Pipe、Socket都需要2次;其次安全性高,不会像Socket会暴露地址,被人替换;由于所有Service都向ServiceManager注册服务,所以Service所在进程死亡后,都会及时通知ServiceManager,避免Client直接检测而导致过重的负载。
Pipe通道,是Linux最主要的通信机制,享内核进程的一块内存,由读、写两个描述符操作数据,管道只是单向,如果双向需要建立两个管道。
通信机制:Server向ServiceManager(C++层,而非Java层,介绍它的启动流程 Binder系列3—启动ServiceManager - Gityuan博客 | 袁辉辉的技术博客)注册,得到虚拟的Uid和Pid,使用Binder通信;Client向ServiceManager请求,得到虚拟的Uid和Pid,以及目标对象的Proxy,底层通过硬件协议传输,使用Binder通讯。
通信时Client手持Proxy,ServiceManger进行转换,调用到Server。三者运行在三个独立进程中。Client/Sever全双工,互为Sever/Client。
1、前者的用户服务和内核服务(进程、内存管理等),在不同的地址空间;后者在相同的地址空间。
2、前者将服务主要放在内核之外,自身作为一个消息中转站;后者将功能集于一身。
3、前者体积小、反应速度慢、拓展性强、安全性强(一个服务崩溃,不至于全体崩溃),后者相反。
4、前者的代表有Symbian、Mac OS X等,后者有Linux、Windows、Solaris等。
参考:
微内核和宏内核的不同 - 掘金
[OS] 微内核和宏内核的区别 - SegmentFault 思否
实际案例:
Vivo7.0以上手机,无法弹出自定义Toast(WindowManager通过addView方式,再配合动画),由于Android手机系统权限逐步收紧,导致无法成功申请的“SYSTEM_ALERT_WINDOW”权限。
解决思路:先看权限是否被收回,其次看使用系统Toast是否可行,最后尝试降级使用WindowManager。
解决办法,降低WindowManager.LayoutParam的flag等级,使用2000以下的等级,比如LAST_SUB_WINDOW(次级window1999)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。