需求
一個通信通道,實現(xiàn)跨進程的的Socket網(wǎng)絡(luò)通信。
具體的通信通道的圖如下。

需求分析
- 我們需要一個進程一直做通信通道的事情,業(yè)務(wù)進程把數(shù)據(jù)通過進程間通信交給通信進程。
- 通信進程通過Socket通道將數(shù)據(jù)發(fā)給網(wǎng)絡(luò)另外一端的通信進程。
- 接收端的通信進程把數(shù)據(jù)再交給業(yè)務(wù)進程。
android進程間通信基本方式
android進程間通信是使用Binder來傳數(shù)據(jù),而Binder傳輸?shù)臄?shù)據(jù),有一個最為基本的要求,就是要實現(xiàn)Parcelable接口。
ParcelFileDescriptor
ParcelFileDescriptor是android提供的一個數(shù)據(jù)結(jié)構(gòu)。
public class ParcelFileDescriptor
extends Object implements Parcelable, Closeable
ParcelFileDescriptor是可以用于進程間Binder通信的FileDescriptor。支持stream 寫入和stream 讀出
public static class ParcelFileDescriptor.AutoCloseInputStream
extends FileInputStream
public static class ParcelFileDescriptor.AutoCloseOutputStream
extends FileOutputStream
我們可以使用
ParcelFileDescriptor open (File file,
int mode)
來將PacecelFileDescriptor 與File對應(yīng)起來,以實現(xiàn)進程間的文件共享。
我們也可以使用
ParcelFileDescriptor[] createPipe ()
來建立一個pipe通信通道,ParcelFileDescriptor數(shù)組第一個元素是read端,第二個元素是write端,通過write端的AutoCloseOutputStream和read端的AutoCloseInputStream,我們就可以實現(xiàn)進程見的數(shù)據(jù)流傳輸了。
完整的跨進程數(shù)據(jù)傳輸方案如下:
-
文件傳輸
兩端業(yè)務(wù)層都把Uri對應(yīng)的ParcelFileDescriptor發(fā)送給通信層,發(fā)送端通信層從AutoCloseInputStream中取數(shù)據(jù)發(fā)送,接收端通信層獲取到數(shù)據(jù)后,寫入到AutoCloseOutputStream中。
流傳輸

發(fā)送端:
1. 業(yè)務(wù)層調(diào)用getOutputStream向通信層發(fā)起請求
2. 通信層通過creatPipe 建立一個ParcelFileDescriptor數(shù)組,并將write端的pipe[1]返回給業(yè)務(wù)層
3. 業(yè)務(wù)層得到pipe[1](ParcelFileDescriptor)后,可以通過AutoCloseOutputStream寫入數(shù)據(jù)
4. 從通信層的pipe[0]的AutoCloseInputStream中讀出數(shù)據(jù)通過socket發(fā)送出去
接收端:
1. 業(yè)務(wù)層調(diào)用getInputStream向通信層發(fā)起請求
2. 通信層通過creatPipe 建立一個ParcelFileDescriptor數(shù)組,并將read端的pipe[0]返回給業(yè)務(wù)層
3. 業(yè)務(wù)層得到pipe0后,可以通過AutoCloseInputStream讀取數(shù)據(jù)。(如沒有數(shù)據(jù),則阻塞,一直等到有數(shù)據(jù)為止)
4. socket中讀取數(shù)據(jù),寫入到通信層的pipe[1]的AutoCloseOutputStream。(pipe[1]一旦寫入,第三步中pipe[2]就可以讀取出數(shù)據(jù))
