(转)Android 匿名共享内存demo篇(一)

   Android系统的IPC方式通常为:文件、socket、binder、messenger、AIDL、ContentProvider,此外还有个Anonymous Shared Memory(匿名共享内存),这篇文章介绍Ashm基础使用相关知识。

   Android api27加入了SharedMemory类,27之前需要通过反射去拿到文件描述符。

    demo为MainActivity和一个远程服务(指定了process的service)之间的通信,步骤如下:

1、创建aidl文件IMemoryAidlInterface

interface IMemoryAidlInterface {
   ParcelFileDescriptor getParcelFileDescriptor();
}

1、创建一个服务并在manifest文件中指定process

<service android:name=".MemoryFetchService"
            android:process=":ashm"/>

在服务MemoryFetchService中创建共享内存虚拟文件并设置size,写入内容为一个数组。

public class MemoryFetchService extends Service {
    private static final String TAG = "MemoryFetchService";
    private static final String SHM_FILE_NAME = "test_memory";
    @Override
    public IBinder onBind(Intent intent) {
        return new MemoryFetchStub();
    }
    static class MemoryFetchStub extends IMemoryAidlInterface.Stub {
        @Override
        public ParcelFileDescriptor getParcelFileDescriptor() throws RemoteException {
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1) {
                MemoryFile memoryFile = null;
                try {
                    memoryFile = new MemoryFile(SHM_FILE_NAME, 1024);
                    memoryFile.getOutputStream().write(new byte[]{1, 2, 3, 4, 5});
                    Method method = MemoryFile.class.getDeclaredMethod("getFileDescriptor");
                    FileDescriptor des = (FileDescriptor) method.invoke(memoryFile);
                    return ParcelFileDescriptor.dup(des);
                } catch (Exception e) {
                    Log.d(TAG, "getParcelFileDescriptor: exception : " + e.toString());
                }
            }else {
                //TODO use SharedMemory to get fd
 
            }
 
            return null;
        }
    }
}

在MainActivity中绑定服务,读取共享内存文件中的内容:

private void bind() {
        Intent intent = new Intent(MainActivity.this, MemoryFetchService.class);
        bindService(intent, new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
 
                byte[] content = new byte[10];
                IMemoryAidlInterface iMemoryAidlInterface
                        = IMemoryAidlInterface.Stub.asInterface(service);
                try {
                    ParcelFileDescriptor parcelFileDescriptor 
                    = iMemoryAidlInterface.getParcelFileDescriptor();
                    FileDescriptor descriptor = parcelFileDescriptor.getFileDescriptor();
                    FileInputStream fileInputStream = new FileInputStream(descriptor);
                    int read = fileInputStream.read(content);
                    Log.d(TAG, "onServiceConnected: read == " + read);
                } catch (Exception e) {
                    Log.d(TAG, "onServiceConnected: exception: " + e.toString());
                }
            }
 
            @Override
            public void onServiceDisconnected(ComponentName name) {
 
            }
        }, Service.BIND_AUTO_CREATE);
    }

debug可以看到content中的内容即为在MemoryFetchService中写入的内容。

adb shell进入设备后,通过lsof|grep "test_memory"可以查看到创建的匿名共享内存虚拟文件:

130|Galileo:/ # lsof |grep "test_memory"  
com.***.ash 27421     u0_a73  mem   unknown  

到这里Android匿名共享内存简单使用demo已经完了,代码在这里clone。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值