- 大体了解Android通信框架
1.volley
Volley 的中文翻译为“齐射、并发”,是在 2013 年的 Google 大会上发布的一款 Android 平台网络通信库,具有网络请求的处理、小图片的异步加载和缓存等功能,能够帮助 Android APP 更方便地执行网络操作,而且更快速高效。
优点: (1)自动调度网络请求; (2)高并发网络连接; (3)通过标准的 HTTP cache coherence(高速缓存一致性)缓存磁盘和内存透明的响应; (4)支持指定请求的优先级( 请求队列的优先级排序); (5) 提供多样的取消机制:网络请求 cancel 机制,我们可以取消单个请求,或者指定取消请求队列中的一个区域; (6)框架容易被定制,例如,定制重试或者回退功能; (7)包含了调试与追踪工具; (8)默认 Android2.3 及以上基于 HttpURLConnection,2.3 以下使用基于 HttpClient (9)提供简便的图片加载工具(其实图片的加载才是我们最为看重的功能)
缺点: (1)不能下载文件:这也是它最致命的地方
2.Android-async-http
Android-async-http 是一个强大的网络请求库,这个网络请求库是基于 Apache HttpClient 库之上的一个异步网络请求处理库,网络处理均基于 Android 的非 UI 线程,通过回调方法处理请求结果。 android-async-http 是一个强大的第三方开源网络请求库。可惜的是 Android 6.0 (api 23) SDK,不再提供 org.apache.http.* (只保留几个类)。
优点: (1) 在匿名回调中处理请求结果 (2) 在 UI 线程外进行 http 请求 (3) 文件断点上传 (4) 智能重试 (5) 默认 gzip 压缩 (6) 支持解析成 Json 格式 (7) 可将 Cookies 持久化到 SharedPreference
3.Afinal框架
Afinal 是一个 android 的 sqlite orm 和 ioc 框架。同时封装了android中的http框架,使其更加简单易用;使用 finalBitmap,无需考虑 bitmap 在 android 中加载的时候 oom 的问题和快速滑动的时候图片加载位置错位等问题。
Afinal的宗旨是简洁,快速。约定大于配置的方式。尽量一行代码完成所有事情。
Afinal主要是分四个模块: (1) 数据库模块:android 中的 orm 框架,使用了线程池对 sqlite 进行操作。 (2) 注解模块:android 中的 ioc 框架,完全注解方式就可以进行UI绑定和事件绑定。无需 findViewById 和 setClickListener 等。其实它后面是使用反射来进行初始化的。 (3) 网络模块:通过 httpclient 进行封装 http 数据请求,支持 ajax方式加载,支持下载、上传文件功能。 (4) 图片缓存模块:通过 FinalBitmap,imageview 加载 bitmap 的时候无需考虑 bitmap 加载过程中出现的 oom 和 android 容器快速滑动时候出现的图片错位等现象。
4.xUtils
xUtils跟Afinal是同类型的框架, 现在作者已经两三年前就没有进行更新了。
5.OKHttp
OkHttp 是一个相对成熟的解决方案,据说 Android4.4 的源码中可以看到 HttpURLConnection 已经替换成 OkHttp 实现了。在 Android 6.0 中底层的源码已经使用了 OKHttp ,这个是可以确定的。 OkHttp 处理了很多网络疑难杂症:会从很多常用的连接问题中自动恢复。如果您的服务器配置了多个IP地址,当第一个 IP 连接失败的时候,OkHttp 会自动尝试下一个 IP。OkHttp 还处理了代理服务器问题和 SSL握手失败问题。 使用 OkHttp 无需重写您程序中的网络代码。OkHttp 实现了几乎和Java.NET.HttpURLConnection 一样的API。如果你用了 Apache HttpClient,则 OkHttp 也提供了一个对应的 okhttp-apache 模块。
6.retrofit
其实 retrofit 是根据 OKHttp 封装的框架,它的底层网络请求就是使用OKHttp的,这个框架的作者也是非常有名的,就是 Jake Wharton 。简直就是我的偶像啊!
优点: (1)支持 okhttp (2)注解处理,简化代码 (3)支持上传和下载文件 (4)支持自己更换解析方式 (5)支持多种http请求库
- 理解Android通信机制Binder、AIDL与HIDL,解释其原理
Binder
在Android应用、Android系统开发的时候,相信很多人都听过Binder的概念,而且无意间就用到了Binder机制,例如:写一个应用打开手电筒功能,某个应用启动服务等。 这些动作都涉及到一个概念-进程间通信。Android 中的每个应用都是独立的进程,都有自己虚拟内存,两个进程之间不能互相访问数据。 在Android中,应用进程间互相访问数据,常用的通信方式就Binder。
Binder通信模型
Binder机制的目的是实现IPC(Inter-Process Communication),即Client和Server之间的通信。
其中Server,Client,ServiceManager运行于用户空间,Binder驱动运行于内核空间。这四个角色的关系和互联网类似:Server是服务器,Client是客户终端,ServiceManager是域名服务器(DNS),驱动是路由器。
一些概念的理解
1)IPC (进程间通信-Inter process communication)
IPC属于通信机制,Android中常用的IPC通信:管道、共享内存、消息队列、信号量、socket、binder。
2)RPC (远程过程调用 Remote Procedure call)
RPC属于通信机制中的调用方法,目的:不同的进程之间,一个进程调用另一个进程的对象。
RPC在调用一个远程过程后,自己进入等待状态,传往远程过程的参数包括过程参数,返回参数包括执行结果;
当收到包括执行结果的消息后,本地进程从消息中取得结果,调用进程重新开始执行。在服务器一方,有一个程序在等待调用,当有一个调用到达时,服务器进程取得进程参数,计算结果,然后返回结果。
调用可以同步的也可以是异步的;服务器可以创建一个线程来接收用户请求,也可以自己来接收用户请求
3)代理模式
为其他对象提供代理对象,以控制对这个对象的访问。
由于进程隔离的存在,一个进程内部的对象对另外一个进程来说没有任何意义。另外如果是代理对象的话,它可以存在各个进程内,就好比咱们的AMS和PMS。
4)进程隔离
进程隔离是为保护操作系统中进程互不干扰而设计的一组不同硬件和软件的技术。这个技术是为了避免进程A写入进程B的情况发生。进程的隔离实现,使用了虚拟地址空间。进程A的虚拟地址和进程B的虚拟地址不同,这样就防止进程A将数据信息写入进程B。
5)内核空间
可以访问受保护的内存空间,有访问底层硬件设备的所有权限。
6)用户空间
相对于内核空间,上层应用程序所运行的空间以及Native层进程运行的空间就是用户空间,用户空间访问内核空间的唯一方式就是系统调用。
7)系统调用/内核态/用户态
从逻辑上看,内核空间和用户空间是独立的,那么用户空间总要有办法调用内核空间,唯一的调用方式就是系统调用(System Call),通过这个统一入口接口,所有的资源访问都是在内核的控制下执行,以免导致对用户程序对系统资源的越权访问,从而保障了系统的安全和稳定。
当一个任务(进程)执行系统调用而陷入内核代码中执行时,我们就称进程处于内核运行态(或简称为内核态)。
当进程在执行用户自己的代码时,则称其处于用户运行态(用户态)。
什么是Binder?
Binder的英文意思是粘结剂,把两个不相关的进程粘在一起,让两个进程可以进行数据交互。 比如我们写一个应用,打开手电筒功能,那么要把打开这个动作,发给管理服务,这个发送的过程就是通过Binder机制来实现。
为什么要用Binder?
Android使用的Linux内核拥有着非常多的跨进程通信机制,比如管道、共享内存、消息队列、信号量、socket等;为什么还需要单独搞一个Binder出来呢? 主要有两点,性能和安全。
1)高效
Binder只需要一次拷贝就能将A进程用户空间的数据为B进程所用
数据从用户空间拷贝到内核中的时候,是直接拷贝到目标进程的内核空间,这个过程是在请求端线程中处理的,只不过操作对象是目标进程的内核空间。
Binder拷贝方式: 数据发送端(虚拟内存) copy_from_user --> 内核虚拟内存 <–mmap–> 数据接收端(虚拟内存) 内核虚拟内存和数据接收端虚拟内存采用mmap映射到同一块物理内存,不存在拷贝动作,数据发送端(Client)要把IPC数据 拷贝到内核虚拟内存空间,存在一次拷贝,所以Binder只存在一次内存拷贝
管道、队列等需要两次内存拷贝: 发送方缓存区–memcpy–>内核缓存区 --memcpy–>接收方缓存区 ,存在两次拷贝
共享内存SMD(Shared Memory Driver),虽然无需拷贝,但控制复杂,难以使用。 socket作为一款通用接口,其传输效率低,开销大,主要用在跨网络的进程间通信和本机上进程间的低速通信。
2)安全
Binder机制为每个进程分配了UID/PID来作为鉴别身份的标示,从协议本身就支持对通信双方做身份校检,因而大大提升了安全性。
什么是AIDL
AIDL:Android Interface Definition Language,即Android接口定义语言。 通过AIDL来制定一些规则,规定进程间能进行哪些交流
如何使用AIDL文件来完成跨进程通信?
在进行跨进程通信的时候,在AIDL中定义的方法里包含非默认支持的数据类型与否,我们要进行的操作是不一样的。如果不包含,那么我们只需要编写一个AIDL文件,如果包含,那么我们通常需要写 n+1 个AIDL文件( n 为非默认支持的数据类型的种类数)——显然,包含的情况要复杂一些。
使数据类实现 Parcelable 接口
由于不同的进程有着不同的内存区域,并且它们只能访问自己的那一块内存区域,所以我们不能像平时那样,传一个句柄过去就完事了——句柄指向的是一个内存区域,现在目标进程根本不能访问源进程的内存,那把它传过去又有什么用呢?所以我们必须将要传输的数据转化为能够在内存之间流通的形式。这个转化的过程就叫做序列化与反序列化。简单来说是这样的:比如现在我们要将一个对象的数据从客户端传到服务端去,我们就可以在客户端对这个对象进行序列化的操作,将其中包含的数据转化为序列化流,然后将这个序列化流传输到服务端的内存中去,再在服务端对这个数据流进行反序列化的操作,从而还原其中包含的数据——通过这种方式,我们就达到了在一个进程中访问另一个进程的数据的目的。而通常,在我们通过AIDL进行跨进程通信的时候,选择的序列化方式是实现 Parcelable 接口。
HIDL说明
HIDL的全称是HAL interface definition language(硬件抽象层接口定义语言),在此之前Android 有AIDL,架构在Android binder 之上,用来定义Android 基于Binder通信的Client 与Service之间的接口。HIDL也是类似的作用,只不过定义的是Android Framework与Android HAL实现之间的接口。
|