• 跨进程通信--共享内存(ashmem)实例


    文章目录

    在之前的文章 ashmem原理中提到过,ashmem 通信原理是每个进程打开同一个文件,所以文件描述符需要通过其他方式传递给其他进程,所以这里采用了 Service + aidl 的方式把共享内存的文件描述符传递过去。然后客户端获取到的文件描述符读取该内存下的内容具体步骤如下:其中 MemoryFile 是通过 ashmem 实现的

    Server 端

    • 第一步定义 aidl 接口,如何使用 aidl 略
    // IFileDescriptorInterface.aidl
    package com.process.server;
    
    interface IFileDescriptorInterface {
    	// 定义接口 返回 ParcelFileDescriptor 文件描述符
          ParcelFileDescriptor getPfd();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    ParcelFileDescriptor 实现了Parcelable 所以可以通过binder传输。

    • 接下来定义 service ,为了方便测试只是简简单单的创建了个 MemoryFile 并返回操作符,MemoryFile 内部采用了ashmem 。记住在 manifest 中注册 service 并且设置 action 因为不是本地 service。
    class MyService : Service() {
    
        /**
         * aidl 定义获取文件描述符的方法
         */
        var stub: IFileDescriptorInterface.Stub = object : IFileDescriptorInterface.Stub() {
            @Throws(RemoteException::class)
            override fun getPfd(): ParcelFileDescriptor {
                return createMemoryFile()
            }
        }
        
        override fun onBind(intent: Intent): IBinder {
            return stub
        }
    
        /**
         * 创建
         * @return ParcelFileDescriptor
         */
        fun createMemoryFile(): ParcelFileDescriptor {
            // 定义空间大小 这里只是随便定义了哥 1024
            val memoryFile = MemoryFile("test_ashmem", 1024)
            val writeString = "hi client,am server msg... "
            memoryFile.outputStream.write(writeString.toByteArray())
            // 可以接下来写各种想写的东西...
            val method: Method = memoryFile.javaClass.getDeclaredMethod("getFileDescriptor")
            val fd = method.invoke(memoryFile) as FileDescriptor
            return ParcelFileDescriptor.dup(fd);
        }
    }
    
    • 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

    客户端准备:

    • 客户端要定义和服务端一样的 aidl 规则:
    package com.process.server;
    
    // Declare any non-default types here with import statements
    
    interface IFileDescriptorInterface {
        ParcelFileDescriptor getPfd();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 接下来连接 service
    class MainActivity : AppCompatActivity() {
    
        private val conn = object : ServiceConnection {
            override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
                val asInterface = IFileDescriptorInterface.Stub.asInterface(service)
                val pfd = asInterface.pfd
                val fileDescriptor = pfd.fileDescriptor
                val fis = FileInputStream(fileDescriptor)
                val string = fis.bufferedReader().use { it.readText() }
                Log.e("tag", "read result = $string")
            }
    
            override fun onServiceDisconnected(name: ComponentName?) {
                Log.e("tag", "onServiceDisconnected")
            }
        }
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
        }
    
        fun bindService(view: View) {
            val intent = Intent()
            intent.component = ComponentName("com.process.server", "com.process.server.MyService")
            val bindService = bindService(intent, conn, Context.BIND_AUTO_CREATE)
            Log.e("tag", "bindService = $bindService")
        }
    }
    
    • 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
  • 相关阅读:
    content向background发送消息的异步消息返回
    6.Docker网络
    全面总结C++类模板使用的基础知识
    【面试高频题】难度 2/5,回溯算法经典运用
    单链表思路讲解+C语言代码实现
    Python使用正则表达式去除base64编码前缀
    界面控件DevExpress WinForm v22.2——即将拥有新的HTML & CSS模板
    训练营第三十五天动态规划(基础题part1)
    [附源码]计算机毕业设计基于Springboot校园招聘系统
    指纹浏览器开发指南-EasyBR
  • 原文地址:https://blog.csdn.net/ldxlz224/article/details/126387305