赞
踩
一个通信通道,实现跨进程的的Socket网络通信。
具体的通信通道的图如下。
android进程间通信是使用Binder来传数据,而Binder传输的数据,有一个最为基本的要求,就是要实现Parcelable接口。
ParcelFileDescriptor是android提供的一个数据结构。
文件描述符,是一种程序读写已打开文件、socket的对象。
FileDescriptor对象,它代表了原始的Linux文件描述符
ParcelFileDescriptor对象,是原始文件描述符的一个复制,对象跟fd不同,但都是操作同一个底层文件流以及文件位置指针
- 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对应起来,以实现进程间的文件共享。
我们也可以使用
ParcelFileDescriptor[] createPipe ()
来建立一个pipe通信通道,ParcelFileDescriptor数组第一个元素是read端,第二个元素是write端,通过write端的AutoCloseOutputStream和read端的AutoCloseInputStream,我们就可以实现进程见的数据流传输了。
文件传输
两端业务层都把Uri对应的ParcelFileDescriptor发送给通信层,发送端通信层从AutoCloseInputStream中取数据发送,接收端通信层获取到数据后,写入到AutoCloseOutputStream中。
流传输
发送端:
1. 业务层调用getOutputStream向通信层发起请求
2. 通信层通过creatPipe 建立一个ParcelFileDescriptor数组,并将write端的pipe[1]返回给业务层
3. 业务层得到pipe[1](ParcelFileDescriptor)后,可以通过AutoCloseOutputStream写入数据
4. 从通信层的pipe[0]的AutoCloseInputStream中读出数据通过socket发送出去
接收端:
1. 业务层调用getInputStream向通信层发起请求
2. 通信层通过creatPipe 建立一个ParcelFileDescriptor数组,并将read端的pipe[0]返回给业务层
3. 业务层得到pipe0后,可以通过AutoCloseInputStream读取数据。(如没有数据,则阻塞,一直等到有数据为止)
4. socket中读取数据,写入到通信层的pipe[1]的AutoCloseOutputStream。(pipe[1]一旦写入,第三步中pipe[2]就可以读取出数据)
简单的ParcelFileDescriptor使用——pipe
- public class DemoParcefliledescriptor extends AppCompatActivity {
-
- private static final String TAG = "DemoPFD";
-
- private static final String[] PERMISSIONS = {
- Manifest.permission.WRITE_EXTERNAL_STORAGE,
- };
- private static final int PERMISSIONS_CODE = 3006;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_demo_null);
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- requestPermissions(PERMISSIONS, PERMISSIONS_CODE);
- }
-
- FileOutputStream outputStream = new FileOutputStream(getStreamFd());
- try {
- outputStream.write(99);
- outputStream.write(98);
- outputStream.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
-
- private FileDescriptor getStreamFd() {
- ParcelFileDescriptor[] pipes = null;
-
- try {
- pipes = ParcelFileDescriptor.createPipe();
- new TransferThread(new ParcelFileDescriptor.AutoCloseInputStream(pipes[0])).start();
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- return pipes[1].getFileDescriptor();
- }
-
- static class TransferThread extends Thread {
- InputStream in;
- FileOutputStream out;
-
- TransferThread(InputStream in, FileOutputStream out) {
- this.in = in;
- this.out = out;
- }
-
- TransferThread(InputStream in) {
- this.in = in;
-
- File outFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/zlq_pdf");
- Log.i(TAG, "File: " + outFile.getAbsolutePath());
-
- try {
- out = new FileOutputStream(outFile);
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- }
- }
-
- @Override
- public void run() {
- byte[] buf = new byte[1024*2];
-
- int len;
- try {
- while((len=in.read(buf)) > 0) {
- out.write(buf, 0, len);
- Log.i(TAG, "out:" + len);
-
- }
-
- in.close();
- out.flush();
- out.getFD().sync();
- out.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。