IPC机制 - Android开发艺术探索读书笔记(第二章)

第二章 - IPC机制

2.1 Android IPC简介

1、IPC(Inter-Process Communication)进程间通信或跨进程通信

2、线程与进程?

    线程 -CPU调度最小单元

    进程 -①有限的系统资源一个执行单元

              ②可包含多个线程

 

2.2 Android中的多进程模式

1、Android使用多进程唯一方法 - 指定android:process属性

2、默认进程名是包名

    android:process= “A”

    A就是所指定的进程名

    如果":A"那就是在默认进程名(包名)后面街上":A"

3、!注意:开启多进程并不是简单地给四大组件指定android:process

      原因:开启多进程后,每一个进程拥有独立的虚拟机(不同虚拟机在内存分配上有不同的地址空间),Application,以及内存空间

      导致的问题:

      ①静态成员变量和单例模式完全失效

      ②线程同步机制完全失效

      ③SharePreferences可靠性下降(SP底层通过读写xml实现)

      ④Application多次创建

4、解决方法 - 跨进程通信

      例如:Intent、共享文件、SharePreferences、Binder的Messenger和ADIL以及相关Socket等

5、IPC基本概念 - Serializable接口、Parcelable接口以及Binder

   Serializable接口:

    ①采用ObjectOutputStream序列化、ObjectInputStream反序列化

    ②serialVersionUID不是必须的,可以用来辅助序列化与反序列化

      序列化时候会将serialVersionUID写入序列化文件中 ,反序列化时候会对比当前类的serialVersionUID,不一致则反序列化失败

   Parcelable接口:

    ①Parcel类内部包装了可序列化的数据 

    ②writeToParcel(Parceldest, int flags)方法 - 序列化功能

 

另:书本上相关描述并不详细,从网上补充了相关知识

Serializable与Parcelable接口的原理与区别

http://blog.csdn.net/androiddevelop/article/details/22108843?utm_source=tuicool&utm_medium=referral

 

区别与选取:

Serializable使用IO读写存储在硬盘上,而Parcelable是直接在内存中读写,很明显内存的读写速度通常大于IO读写,所以在Android中通常优先选择Parcelable。

 

 

6、Binder的使用及上层原理

    ①IPC角度 - Binder是Android中一种跨进程通信方式

       Android Framework角度 -Binder是ServiceManager连接各种Manager的桥梁

       Android应用层角度 - Binder是客户端与服务器端进行通信的媒介

    ②AIDL(Android interface Definition Language)示例分析Binder原理

       建立了aidl后,gen目录下会自动生成一个.java文件

       该类继承IInterface接口,声明了两个aidl中已声明的方法,并声明两个整型id用于标识这两个方法;

       接着,声明了一个内部类Stub(一个Binder类);

       当客户端与服务器端都位于同一个进程,方法调用不会走跨进程的transact过程,而两者位于不同进程时,方法调用就要走跨进程的transact过程,而这个逻辑就是Stub的内部代理Proxy来完成。

       故核心就是实现它的内部类Stub与Stub的内部代理类Proxy

 

详解:

    DESCRIPTOR - Binder唯一标识

   asInterface(android.os.IBinder obj) - 用于转换服务器端Binder对象,转换成客户端所需的AIDL接口类对象

    asBinder - 返回当前Binder对象

   onTransact - 运行在服务器端中的Binder线程池,客户端发起跨进程请求时,远程请求会通过系统底层封装后交由此方法处理。

    Proxy#定义的方法名 - 运行在客户端,客户端远程调用时,创建所需要的输入型Parcel对象_data、输出型Parcel对象_reply、返回值对象List,将参数写入data(如果有参数 ),接着调用transact方法发起RPC,同时挂起当前线程吗,然后服务器端onTransact方法被调用知道RPC过程返回。从_reply取出RPC返回结果,最后返回。

    注意:①因为远程方法耗时,则不能在UI线程发起远程请求

             ②由于服务器端Binder方法运行在Binder线程池,所以Binder方法不论是否耗时,都应采用同步方法实现。

    

    当然,我们也可以手动实现Binder,这与通过AIDL文件让系统工作原理实现是一样的。

    可以说,AIDL文件本质是系统为我们提供的实现Binder的工具

 

另:Android aidl使用详解

http://blog.csdn.net/stonecao/article/details/6425019

             使用AIDL

http://blog.csdn.net/saintswordsman/article/details/5130947

 

 

2.4 Android中的IPC方式

1、Bundle方式

     Bundle实现了Parcelable接口,使用Bundle是最简单的进程通信方法。但是如果传输的数据不是Bundle所支持的,则无法使用。

     Bundle无法支持所要传递的数据时候,通过Intent启动Service组件,让Service在后台计算,计算完毕之后启动目标组件。

      核心思想:需要在A进程的计算任务转移到B进程的后台Service中执行。

2、文件共享方式(数据同步要求不高可以采用)

     A中将结果序列化存到某个文件,B中读取该文件,并将其反序列化。

      注意,多个线程对同一个文件进行读写操作,有可能导致数据丢失。

3、使用Messenger(一种轻量级的IPC方案,底层是AIDL)

      在Messenger中放入需要传递的数据,在不同进程中传递Messenger对象。

      但,如果有大量并发请求时候,Messenger就不太适合了;

      另外,Messenger不能跨进程调用服务器端的方法,需要用到AIDL; 

     使用方法:

      服务器端- 创建Service来处理客户端连接请求,同时创建一个Handler并通过它创建一个Messenger对象,然后在Service的onBind中返回这个Messenger对象底层的Binder。

      客户端- 绑定服务器端Service,绑定成功后用服务器端返回的IBinder对象创建Messenger对象。如果需要服务器回应客户端,则还需要创建一个Handler并创建一个新的Messenger,并把这个Messenger对象通过Messenger的replyTo参数传递给服务器端,服务器端通过这个replyTo参数就可以回应客户端。

 

4、使用AIDL(大量并发请求,Messenger不适合)

     P71~90有具体实现,这里不再累述

 

 服务器端:

    创建Service用来监听客户端请求、创建AIDL文件,将暴露给客户端的接口在这个AIDL接口中声明,最后在Service中实现这个AIDL。

    

 客户端:

    绑定服务器端的Service,将服务器端返回的Binder对象转成AIDL接口所属类型,即可调用AIDL中的方法了。

 

!注意:

    AIDL文件中,并不是所有数据类型都可以使用的。

 

5、使用ContentProvider(底层Binder实现)

    P91~103

    例子:系统预置了许多ContentProvider(通讯录、日程表),可以通过ContentProvider的query、update、insert、delete方法访问这些应用获取相关数据。

    实现:

    写一个类继承ContentProvider并实现六个抽象方法,onCreate、query、update、insert、delete和getType。(onCreate由系统回调并运行在主线程中、其余5个方法由外部回调并运行在Binder线程池中。)

    另:!注意ContentProvider的注册与权限

          !注意query、update、insert、delete四大方法存在多线程并发访问的,内部要注意做好线程同步。

 

6、使用Socket(套接字)

    P103 ~121

    分为流式套接字和用户数据报套接字两种,分别对应于网络的传输控制层中的TCP(面向连接的协议,提供稳定的双向通信功能)和UDP协议(无连

    接,提供不稳定的单向通信功能)

 

Socket使用:

    ①权限声明、不能在主线程中访问网络

    ②服务器端:Service启动时,会在线程中建立TCP服务,当有客户端连接,会生成一个新的Socket(每次创建的Socket可分别和不同的客户端通信)

       当客户端断开连接,服务器端也会相应关闭对应Socket并结束通话线程。

 

2.6选用合适的IPC方式

    方式 -适用场景

    Bundle- 四大组件间的通信

    文件共享- 无并发访问情形,交换简单的数据及时性不高的场景

    AIDL - 一对多通信且有RPC需求

   Messenger - 低并发的一对多即时通信,无RPC需求,或者无需返回结果的RPC需求

   ContentProvider - 一对多的进程间的数据共享

    Socket- 网络数据交换

     

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值