【Android】SharedMemory获取文件描述符

SharedMemory用来实现共享内存操作很方便,也提供了获取文件描述符的方法,但是是hide的,普通app不能访问,

java 复制代码
    /**
     * Returns the backing {@link FileDescriptor} for this SharedMemory object. The SharedMemory
     * instance retains ownership of the FileDescriptor.
     *
     * This FileDescriptor is interoperable with the ASharedMemory NDK APIs.
     *
     * @return Returns the FileDescriptor associated with this object.
     *
     * @hide Exists only for MemoryFile interop
     */
    public @NonNull FileDescriptor getFileDescriptor() {
        return mFileDescriptor;
    }

    /**
     * Returns the backing native fd int for this SharedMemory object. The SharedMemory
     * instance retains ownership of the fd.
     *
     * This fd is interoperable with the ASharedMemory NDK APIs.
     *
     * @return Returns the native fd associated with this object, or -1 if it is already closed.
     *
     * @hide Exposed for native ASharedMemory_dupFromJava()
     */
    @UnsupportedAppUsage(trackingBug = 171971817)
    public int getFd() {
        return mFileDescriptor.getInt$();
    }

可以使用反射区获取fd,但是不够优雅,这里看看另外一个方式,通过parcel处理去间接的获取。

java 复制代码
            Parcel pData = Parcel.obtain();

            sharedMemory.writeToParcel(pData, 0);//Parcelable.PARCELABLE_WRITE_RETURN_VALUE

            //here
            pData.setDataPosition(0);
            ParcelFileDescriptor parcelFileDescriptor = pData.readFileDescriptor();

这样就可以获取到文件描述符了,注意,pData.setDataPosition(0);是必须的。

在 Android 中,SharedMemory(共享内存)是一种允许不同进程共享同一块内存区域的机制,常用于高效传输大量数据(如图像、视频等)。以下是其核心要点:


1. 核心概念

  • 作用:避免传统 IPC(如 Binder)的数据拷贝开销,实现跨进程高效数据共享。

  • 底层机制 :基于 Ashmem(Android Shared Memory Driver),一种 Linux 匿名共享内存的优化版本,支持内存区域的动态清理和权限控制。


2. 关键类与 API

  • SharedMemory(API 26+):封装了 Ashmem 的操作,提供创建、映射和管理共享内存的方法。

  • ParcelFileDescriptor:用于跨进程传递共享内存的文件描述符(FD)。

  • MemoryFile(旧版 API 的替代):基于 Ashmem,适用于 API 较低的场景。


3. 使用步骤

创建与映射共享内存

kotlin

复制

复制代码
// 1. 创建 SharedMemory 实例
val sharedMemory = SharedMemory.create("my_shmem", 1024)

// 2. 映射到当前进程内存(可读写)
val buffer = sharedMemory.mapReadWrite()

// 3. 写入数据
buffer.putInt(0, 42) // 示例:在位置 0 写入 Int 值

// 4. 跨进程传递 FD
val pfd = ParcelFileDescriptor.fromFd(sharedMemory.fileDescriptor)
// 通过 Intent/Bundle/AIDL 传递 pfd 给其他进程
其他进程访问共享内存

kotlin

复制

复制代码
// 1. 接收 ParcelFileDescriptor(假设通过 Binder 传递)
val pfd: ParcelFileDescriptor = ...

// 2. 通过 FD 创建 SharedMemory
val sharedMemory = SharedMemory.createFromFd(pfd)

// 3. 映射内存(根据权限选择只读/读写)
val buffer = sharedMemory.mapReadOnly()

// 4. 读取数据
val value = buffer.getInt(0) // 读取位置 0 的 Int 值

// 5. 使用后清理
sharedMemory.unmap(buffer)
sharedMemory.close()

4. 注意事项

  • 同步问题:共享内存无内置同步机制,需自行处理(如使用锁、信号量等)。

  • 内存泄漏 :确保及时调用 unmap()close() 释放资源。

  • 兼容性SharedMemory 需 API 26+,低版本可使用 MemoryFile

  • 权限控制 :通过 setProtect() 设置读写权限(如 Protection.READ)。


5. 使用场景

  • 高性能数据传输:如图像处理、音视频编解码、游戏资源加载。

  • 跨进程大数据共享:替代 Binder 的 1MB 限制,避免序列化开销。


6. 对比其他 IPC

机制 性能 数据大小限制 复杂度
Binder 1MB
文件/ContentProvider
SharedMemory

7. 代码示例(跨进程传递 FD)

发送端
复制代码
val sharedMemory = SharedMemory.create("image_buffer", 1024 * 1024)
val pfd = ParcelFileDescriptor.fromFd(sharedMemory.fileDescriptor)
val intent = Intent().apply { putExtra("shared_fd", pfd) }
startActivity(intent)
接收端
复制代码
val pfd = intent.getParcelableExtra<ParcelFileDescriptor>("shared_fd")
val sharedMemory = SharedMemory.createFromFd(pfd)
val buffer = sharedMemory.mapReadWrite()
// 处理数据...

通过合理使用 SharedMemory,可以显著优化 Android 中跨进程的大数据交互性能,但需注意同步和资源管理。

参考资料:

https://blog.51cto.com/u_16213375/11974814

相关推荐
Jerry14 小时前
构建 Compose 界面
android
Y多了个想法14 小时前
Linux驱动开发与Android驱动开发
android·linux·驱动开发
2501_9160074717 小时前
从零开始学习iOS App开发:Xcode、Swift和发布到App Store完整教程
android·学习·ios·小程序·uni-app·iphone·xcode
姝然_952717 小时前
ConstraintLayout属性详解
android
2501_9160088918 小时前
前端工具全景实战指南,从开发到调试的效率闭环
android·前端·小程序·https·uni-app·iphone·webview
浅影歌年19 小时前
Android和h5页面相互传参
android
用户693717500138419 小时前
搞懂 Kotlin 软关键字与硬关键字:灵活命名与语法陷阱全解析
android
下位子20 小时前
『OpenGL学习滤镜相机』- Day2: 渲染第一个三角形
android·opengl
风语者日志21 小时前
[LitCTF 2023]这是什么?SQL !注一下 !
android·数据库·sql
2501_915921431 天前
iOS 26 CPU 使用率监控策略 多工具协同构建性能探索体系
android·ios·小程序·https·uni-app·iphone·webview