目录
四 Android架构探究
五 大骨架仿真
六 Android实例分析思路拓展
四 Android架构探究
首先,Android系统所带来的好处,就在于它本身代码的开放性,这提供了一个学习、借鉴的平台。这对分析仿真而言,本身就是一大利好,可以更深入的探究,更加接近真实情况。其次,从Android系统中所学的东西也可以运用于其他一些系统的设计中(额外的,它使用的优秀开源软件及使用方法也是值得学习运用的)。最后,这种公开性所开放出来的底层修改机会,也使得在Android系统本身上可以有一番作为,比如对系统进行优化。
Android系统的作用是支撑一个个的APP,所以,每一个APP都应该平等的享用系统的资源,不管是硬件资源还是软件资源,并且,APP之间的地位也是平等的。如此一来,就存在两个部分,一个是系统管理部分,为各个APP服务,一个是APP们,平等的跟管理者交互。对于Windows系统,也是如此。管理者提供系统服务,APP们通过管理者,使用系统资源。将这种情况简化,那么一般的嵌入式系统产品,就是一个APP跟一些个服务交互。因为不会有人为这些个特殊的嵌入式产品编写APP,所以,不需要对服务和服务的使用者进行过多封装。反而,从这个角度来看,因为共享需求,Android将系统资源封装,供每个APP使用则是合理的,而且也是得体的,既不存在大材小用问题,也不存在设计浪费问题,更不存在多而无用的问题。
框架在此中,充当了中间件的作用。
框架在此中,也类似于C库,作为一种共享库,存在于每一个APP中。因此,框架是一套逻辑,将各个部分管理(粘)到一起的逻辑。就如同博主在这篇讨论框架的文章中所述,软件架构及几种典型框架_龙赤子的博客-CSDN博客_软件架构,通常我们看到main函数是第一个被调用的入口函数,但是实际上,main只是程序框架给我们的入口。我们在Android开发中,不用从main开始第一行代码编写,也只是因为框架帮我们实现了main该做的事情。这个过程中,框架进行了二次封装。框架设计了一套逻辑共享库,每一个应用集成该共享库,应用不用实现main接口,只需集成共享库的类接口即可。应用起来后,实现在共享库中的框架逻辑会调用main接口,并且会自动调用运行周期各个点上注册的函数。如此,我们写的代码,就跟框架融合在一起了。
最终,大家共享的就是逻辑,就是框架中的逻辑。框架中的全局变量不会产生影响,因为应用之间是相互隔离的。框架只需处理好内部的共享即可。对于应用之间的交互,框架会依赖系统服务完成。关于这些,可以参考之前第三部分的说明。
再多说一些。我们可以从不同角度看框架的作用与价值。注意,框架不是虚的,它有承载的实体。从静态的角度来看,架构是一个层,既是分割层,也是中间层,更是粘合层。
框架提供逻辑与功能共享,为所有服务和APP所共享。此时,从进程角度来看,框架的逻辑存在于每一个实体进程之中。大家按照框架给的统一模式来编写个性代码。如果还以房子为例的话,统一的框架表示了房屋的承重、管道等,大家是一样的,但是每家利用这些资源装修后的房子,是不一样的。再举个之前一直用的形象例子,开网店。框架提供的各种资源是统一接口的,比如CPU、内存、存储、网络、显示等等。每一家利用这些资源,开发构建的各自网店不仅样式不一样,功能更是多了去了。卖书的店铺跟卖手机的店铺关注的点肯定是不一样的。
基于上面的分析和Android系统的学习,结合第三部分的思考,整理了Android系统与Android内部Framework框架之间关系的一幅图,如下:
Android Framework图示说明:
先看左上图,这是Android启动的简略过程。通过这个过程,我们会了解到zygote的原理。这是整个讨论的基础。
再看右上图,上面部分是系统框架和应用的分层对应图。下面是应用的三种运行状态。第一种,应用不需要与外部沟通,只依赖框架内部逻辑。第二种,应用需要通过框架,跟其他服务沟通,完成功能。第三种,应用可用自己与系统底层沟通,完成功能。正常来讲,部分服务实现的也是这种方式,从而将系统资源提供给大家共享。
最后,看下图,粗略展示了几种状态的运行关系。应用和服务依赖框架注册到服务管理模块,并依赖内核提供的沟通机制,实现进程间的通信。这部分是对图上半部分左右两块的另一个视角展示。
对于图中嵌入的诸多小方块,其涉及应用和框架内置的代码逻辑。关于这部分,说明如下:
先从编译开始,用户编写Java文件,提供布局,UI语言等其他文件和资源。Java编译为class字节文件,其他图片、C/C++动态库等资源直接打包,运行时再按照规则处理。
对于Java编译,分三种情况:
第一种,独立不依赖其他模块的Java代码,直接编译为Java字节码即可,设备中的虚拟机会解读这些字节码并执行它们。
第二种,依赖第三方jar文件,编译时需要导入class文件,以便编译时遇到未知接口时可以查找这些依赖文件,找到接口所在文件,并将其关联起来,从而形成一个整体。打包时需要导入安装包中。这也算是框架的一部分,或者说是整个拼图的一部分。
第三种,系统自身提供的jar文件,比如android.jar。需要根据SDK提供的不同版本选择合适的版本使用。构成本身同样为class文件,编译遇到未知接口时会查找连接(这就是为什么IDE中要下载相关的SDK),并形成一个整体。这部分跟第三方依赖库可能有些差异。第三方依赖库是需要打包到安装包中的,因为系统不能保证内部包含特定APP依赖的特定第三方jar。但是对于系统自身提供的jar,可能没必要将所有的都打包到APP中,因为系统在应用环境构建时,公共的部分已经加载到系统中了。这就类似我们用C、C++编写程序,在二进制代码中会标出来需要使用标准库,但是并不实际打包到可执行程序文件中。程序实际加载运行时,操作系统会帮助解决依赖的标准库问题。我想Android也是类似的。
从进程运行角度来看,通过框架的分割,实现了逻辑的相互隔离,并减少了逻辑上的缠绕。框架存在于进程之中,服务于实体之间的交互,也在上图中得到了体现。总的来讲,这部分既是对第三部分的进一步确认和细化,也是我们做框架大骨架仿真的一个基础(一个尝试)。
为强化对上面内容的理解,我们再举两个例子。一个是想象的例子,一个是实际的例子。先看想象的例子:
上面以应用显示为例子。系统中有一个处理显示合成渲染的进程,所有应用要显示的内容,都是告诉该进程来完成的。这个告诉过程,就由框架来完成了。另外,不同应用功能不同,用到框架中的资源也不一样。比如一个带WIFI相关功能的应用跟一个单纯打电话的应用,对框架资源使用的部分肯定是不同的,但这并不影响框架发挥作用。
下面再看看实际的例子。
上面两图展示了博主做的一个IPTV应用架构,该应用基于Android平台。该应用要用到浏览器,并且要对浏览器进行改造,因此,博主将系统的浏览器复制了一份,给该IPTV应用单独提供了一个特供浏览器。这个特制浏览器跟系统原生浏览器基本一致,只是增加了对一些自定义JS对象的支持。
为了给自己的应用提供一个特制浏览器,博主将Android浏览器从底层到上层都复制了一份。这样从静态来看,应用Framework中就包含了两个浏览器核心。只不过我们专门改过的那份核心,别的应用调用不到。从动态来看,应用层代码逻辑复制了一份,底层动态库也复制了一份,所以应用进程空间中,浏览器相关的代码都有两份,而且浏览器中有关线程的创建也会多一份,最终造成的结果就是系统默认自带的那个浏览器核心代码在IPTV应用中永远不会调到,也不会参与网页的渲染。
从这个例子,大家也可以感受一下框架的魅力。
五 大骨架仿真
暂略。
六 Android实例分析思路拓展
补充说明:在第五部分展开之前,再整理一下思路。
实例:Android运行时的情景分析
以运行时内存中的各个进程为对象,来研究各个类的实现。从这个角度看的话,代码的实现都可以看成是逻辑的堆彻,是静态的,提供了设计精巧的条条通道,通过这些通道彼此关联起来,以便再运行时彼此交互。这种思路更加接近于逻辑控制,而我们常常还停留在流程控制上。(其实,我们理解一个事物,往往喜欢从流程入手,这样更容易一些。但当我们认识到一定程度后,流程的东西反而成了拖累。此时,就喜欢从抽象的角度来看待问题,这样能够看到更本质的东西。而那些流程上的细节,已经内化于心,被隐藏起来了)。
另外一种运行时情景分析【进程运行时情景分析】
1 全局变量在任务之外
2 构建内存运行时情景图,比如代码段,数据段等
3 数据结构在内存中的样式和作用
4 深刻理解程序就是数据结构加算法这一说
5 任务也就是线程与进程的内存情景
6 从内存情景图着手,分析代码的执行流程,感受内存中数据结构及其附带的Buffer的变化,实际了解程序执行。
图片1 外框内存田 内框进程 进程内框分任务和数据,参考操作系统概念一书 |
图片2 内存中运行的程序进行拍照,快照图 时刻1 时刻2 时刻3等等的图片,通过加粗变化的地方,感受2和5描述的内容 |
第三种情景分析角度,通过进程分析Android服务。这是很多讲述Android架构的书籍所忽略的一点。使用PS命令看进程及其父子关系,分析各个服务。这是从动的角度来分析逻辑的东西。
其实还可以学架构设计中的做法,分不同的角度来分析,比如逻辑图、框架图、物理图、进程图、开发图等等。就像矩阵的变换一样,东西还是那个东西,但是变化一下角度,就能看到不一样的内容。这里也是如此,通过不同的角度,对程序的运行情景有一个完整的认识。
以上记录一些框框思路,后续有时间补充具体内容。