Android的一些设计思想(201603)

来源:互联网 发布:ubuntu 配置ip地址 编辑:程序博客网 时间:2024/06/16 11:26

> 设计思想

Java面向对象设计思想-堆溢出(OutOfMemoryError),栈溢出(StackOverFlowError),封装、继承、多态性

Android设计思想-四大组件新建,不用new 关键字,而是Framework框架层的IOC控制,Intent, Binder ,进程与线程 Manager(AMS WMS)等;


 > Binder全貌
Native 实现:  IBinder,  BBinder, BpBinder, IPCThread, ProcessState, IInterface, etc
Java 实现:  IBinder, Binder, BinderProxy, Stub, Proxy.
Binder Driver: binder_proc, binder_thread, binder_node, etc.

   Binder IPC机制

     Android系统中大量使用了基于C/S模式的通信方式。诸如短信操作,电话操作,视频音频捕获,传感器等都以服务(Service)的形式提供,并由相应的Server负责管理.
     模式的支持,Android采用了一种基于共享内存的IPC机制——Binder机制。

  binder 通信是一种 client-server 的通信结构, 
    1. 从表面上来看,是 client 通过获得一个 server 的代理接口,对 server 进行直接调用; 
    2. 实际上,代理接口中定义的方法与 server 中定义的方法是一一对应的; 
    3.client 调用某个代理接口中的方法时,代理接口的方法会将 client 传递的参数打包成为 Parcel 对象; 
    4. 代理接口将该 Parcel 发送给内核中的 binder driver. 
    5.server 会读取 binder driver 中的请求数据,如果是发送给自己的,解包 Parcel 对象,处理并将结果返回; 
    6. 整个的调用过程是一个同步过程,在 server 处理的时候, client 会 block 住。
    Binder机制的本质是共享内存,共享内存区的管理完全由Binder驱动来完成,对应用层的Client和Server来说是完全透明的。
    Client和Server均通过函数ioctl与Binder驱动进行数据交互。ioctl是Linux中用于控制I/O设备的函数,提供了一种同时向设备发送控制参数和数据的手段。

 应用和 service 之间的通信会涉及到 2 次 binder 通信。 
   1. 应用向 SM 查询 service 是否存在,如果存在获得该 service 的代理 binder ,此为一次 binder 通信; 
   2. 应用通过代理 binder 调用 service 的方法,此为第二次 binder 通信。

 ProcessState 是以单例模式设计的。每个进程在使用 binder 机制通信时,均需要维护一个 ProcessState 实例来描述当前进程在 binder 通信时的 binder 状态。 
    ProcessState 有如下 2 个主要功能: 
    1. 创建一个 thread, 该线程负责与内核中的 binder 模块进行通信,称该线程为 Pool thread ; 
    2. 为指定的 handle 创建一个 BpBinder 对象,并管理该进程中所有的 BpBinder 对象。 

ProcessState 中有 2 个 Parcel 成员, mIn 和 mOut , Pool thread 会不停的查询 BD 中是否有数据可读,如果有将其读出并保存到 mIn ,同时不停的检查 mOut 是否有数据需要向 BD 发送,如果有,则将其内容写入到 BD 中,总而言之,从 BD 中读出的数据保存到 mIn ,待写入到 BD 中的数据保存在了 mOut 中。
ProcessState 中生成的 BpBinder 实例通过调用 IPCThreadState 的 transact 函数来向 mOut 中写入数据,这样的话这个 binder IPC 过程的 client 端的调用请求的发送过程就明了了 。

 了解了 native 通信机制后,再去分析 JAVA 层的 binder 机制,就会很好理解了。它只是对 native  binder 做了一个封装。

从应用程序的角度看Binder一共有三个方面: 
Native 本地:例如BnABC,这是一个需要被继承和实现的类。 
Proxy 代理:例如BpABC,这是一个在接口框架中被实现,但是在接口中没有体现的类。 
客户端:例如客户端得到一个接口ABC,在调用的时候实际上被调用的是BpABC 




Handler消息机制

与Handle工作的几个组件Looper、MessageQueue各自的作用:
  1.Handler:它把消息发送给Looper管理的MessageQueue,并负责处理Looper分给它的消息
   2.MessageQueue:采用先进的方式来管理Message
   3.Looper:每个线程只有一个Looper,比如UI线程中,系统会默认的初始化一个Looper对象,它负责管理MessageQueue,不断的从MessageQueue中取消息,并将
                    相对应的消息分给Handler处理


> 理解AIDL其工作原理

  关于AIDL的介绍在文档:docs/guide/developing/tools/aidl.html
  关于IBinder的介绍在文档:docs/reference/android/os/IBinder.html
  以及Binder:docs/reference/android/os/Binder.html
  在Android上,一个进程无法正常访问另一个进程的内存,而AIDL可以为你实现。
AIDL是一个接口描述文件,用于实现Android平台上面的RPC,aapt在编译的时候会自动根据规则生成用于IPC的接口和对象,而作为使用者只需要:1.在服务端Service实现接口;2. 在客户端bindService,onServiceConnected时获取接口对象。这里的接口都是AIDL中描述的接口,其他的细节则在由AIDL生成的同名源码文件中。

   本质--脱去内衣
其实AIDL的作用就是对Binder的二个方法:Binder.transact()和Binder.onTransact()进行封装,以供Client端和Server端进行使用。因为实现transact()和onTransact()方法的方式基本上是相同的,所以就可以用模板来生成具体的代码。理论上讲只需要为Client端生成transact()相关代码,为服务端生成onTransact()代码即可,但因为工具无法准确的确定某一个应用到底是Client端还是Server端,所以它就生成所有的代码,放在一个文件中。这就是你看到的自动生成的文件。
还需要注意的一点是Client端的Proxy是组合Binder对象,调用其transact()方法;而服务端必须继承Binder对象,覆写onTransact()方法。为虾米呢?因为Client是主动发起IPC函数Call,所以它可以直接调用Binder的方法来进行IPC。而Server是被动的,是要接收进来的IPC call,但Service自己无法得知啥时候Call会来,因此必须实现回调(onTransact())给Binder,以让Binder在有IPC Call进来的时候告诉Service。
   原理和内幕
AIDL的角色是实现Android平台上面的RPC(Remote Procedure Call)也即远程例程调用。RPC是IPC中的一种,但是它是以调用在本地或者另一个进程,甚至是另一个主机上的方法的机制。RPC的目的就是可以让程序不用担心方法具体是在哪个进程里面或者哪以机器上面,就像正常的本地方法那样去调用即可,RPC机制会处理所有的具体细节。RPC一般用IDL(Interface Definition Language)来描述,实现则要看具体的平台和语言。可以参考Wikipedia来看RPC 和IDL 的更多信息。
AIDL提供Android平台的RPC的支持:开发者仅需要要定义AIDL,做一些相关的适配工作,然后就可以使用这些方法了,不用具体关心接口描述的方法空究竟是在同一个进程中还是在其他的进程中。这些RPC实现的细节由Binder和系统来处理。

    客户Proxy的transact,和服务Stub的onTransact使用二个标识来识别对方:一个是DESCRIPTOR,这个是标识Binder的Token,也就是说是标识服务端和客户端;方法的标识就是TRANSACTION_print,是用来标识调用的是哪个方法。这个理解起来也不是很难,就好比打电话,先要通过通讯的标识电话号码找到相应的人,然后跟人说的时候要告诉他是哪件事(哪个方法)。
接下来可以二个方面来进行深入的研究:
  1. bindService是如何获得Binder对象的(无论是本地时Service的实现,还是远程时的BinderProxy),或者说是如何查询到Binder对象。
这是ServiceConnection.onServiceConnected的调用栈:
  2. Binder.transact()和Binder.onTransact()的细节,这也是具体Binder IPC机制的细节。


> ServiceManager、ActivityManager、XXXManager是干什么的?
  C/S框架及代理 框架IOC

服务进程                          管理的服务
com.android.phone       与通信功能相关的短信、电话服务
mediaserver                    与媒体功能相关的视频、音频服务
system_server                其他服务,如地理位置、蓝牙、网络连接、程序安装卸载等


- AIDL:熟悉AIDL,理解其工作原理,懂transact和onTransact的区别; 

- Binder:从Java层大概理解Binder的工作原理,懂Parcel对象的使用; 
- 多进程:熟练掌握多进程的运行机制,懂Messenger、Socket等; 
- 事件分发:弹性滑动、滑动冲突等; 
- 玩转View:View的绘制原理、各种自定义View; 
- 动画系列:熟悉View动画和属性动画的不同点,懂属性动画的工作原理; 
- 懂性能优化、熟悉mat等工具 
- 懂点常见的设计模式

1.了解SystemServer的启动过程 
2. 了解主线程的消息循环模型 
3. 了解AMS和PMS的工作原理 
4. 能够回答问题”一个应用存在多少个Window?“ 
5. 了解四大组件的大概工作流程 。。。。。。

rx 知道么?图片三级缓存? OOM ? 得说一些思想出来??? Eventbus  volley 之类有熟悉的么,主要是思想?  常见设计模式,你要列出来有哪些??

EvnetBus的下载地址:https://github.com/greenrobot/EventBus.git


> gravity与layout_gravity的区别

android:gravity:设置的是控件自身上面的内容位置
android:layout_gravity:设置控件本身相对于父控件的显示位置。


《未完待续》

0 0
原创粉丝点击