当前位置:   article > 正文

Android 进程间通信,Ashmem共享内存基本使用_android ashmem通信实现

android ashmem通信实现

Android 提供了几种进程间通信的方式,除了Socket,基本都是基于binder实现的。为什么要用共享内存来实现呢?因为binder传输数据被限制在1M,在较大的数据交换一般会使用文件,但效率非常的低,因此使用共享内存是很好的方式。在内存中开辟一块空间,通过binder或者其他方式将fd(文件描述符)传递到客户端或服务端进程,从而实现大文件传输

其中Android提供了封装好的MemoryFile对象,供使用。

具体实现

一,服务端

1,首先在APP内部存储中存放一张图片:路径 data/data/com.example.ashmem_service/files/image.jpg
2,将文件写入到共享内存 并返回ParcelFileDescriptor
2,通过binder将返回的pfd传递给客户端

aidl文件

// IMyAidlInterface.aidl
package com.example.ashmem;

// Declare any non-default types here with import statements

interface IMyAidlInterface {
    ParcelFileDescriptor getPfd();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
public class MyService extends Service {
    @Override
    public void onCreate() {
        super.onCreate();
    }

    IMyAidlInterface.Stub myAidlInterface=new IMyAidlInterface.Stub() {
        @Override
        public ParcelFileDescriptor getPfd() throws RemoteException {
            return createMemory();
        }
    };

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return myAidlInterface;
    }




    //创建共享内存区域
    private ParcelFileDescriptor createMemory() {
        MemoryFile memoryFile=null;
        byte[] bytes =readFile(new File(getFilesDir().getPath(),"image.jpg"));
        try {
       		//创建内存对象 参数一:name 参数二:开辟的内存大小
            memoryFile=new MemoryFile("test_memory",1024*4);
            //将数据写入到内存当中
            memoryFile.getOutputStream().write(bytes);
            //通过反射获取到getFileDescriptor方法,注意
            Method method = MemoryFile.class.getDeclaredMethod("getFileDescriptor");
            //得到文件描述符
            FileDescriptor fd = (FileDescriptor) method.invoke(memoryFile);
            //将文件描述符返回
            return ParcelFileDescriptor.dup(fd);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return null;
    }


    //file文件读取成byte[]
    public static byte[] readFile(File file) {
        RandomAccessFile rf = null;
        byte[] data = null;
        try {
            rf = new RandomAccessFile(file, "r");
            data = new byte[(int) rf.length()];
            rf.readFully(data);
        } catch (Exception exception) {
            exception.printStackTrace();
        } finally {
            closeQuietly(rf);
        }
        return data;
    }
    //关闭读取file
    public static void closeQuietly(Closeable closeable) {
        try {
            if (closeable != null) {
                closeable.close();
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76

二,客户端

拿到fd写入到文件中即可

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private static final String TAG = "MainActivity";
    IMyAidlInterface aidl;
    ParcelFileDescriptor pfd = null;
    private ServiceConnection connection;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        String filePath = this.getFilesDir().getPath();
        File file = new File(filePath + "/image.jpg");
        connection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                aidl = IMyAidlInterface.Stub.asInterface(service);
                try {
                    pfd = aidl.getPfd();
                    FileDescriptor fileDescriptor = pfd.getFileDescriptor();
                    FileInputStream inputStream=new FileInputStream(fileDescriptor);
                    file.createNewFile();
                    FileOutputStream fo = new FileOutputStream(file);
                    int read = inputStream.read();
                    while (read != -1) {
                        fo.write(read);
                        read = inputStream.read();
                    }
                    //关闭流
                    fo.flush();
                    fo.close();
                    inputStream.close();

//                    Log.i(TAG,"接收到的数据:"+new String(content,"UTF-8"));
                } catch (RemoteException | IOException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {

            }
        };
        findViewById(R.id.bindService).setOnClickListener(this);


    }

    private void bindService() {
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.example.ashmem", "com.example.ashmem.MyService"));
        boolean isbind = bindService(intent, connection, Context.BIND_AUTO_CREATE);
        Log.i(TAG, "bindService: "+isbind);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.bindService:
                bindService();
                break;
            default:
                break;
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/447917
推荐阅读
相关标签
  

闽ICP备14008679号