【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

相关推荐
tongyiixiaohuang4 小时前
WMS已发货状态反写金蝶云星空:单策略实战教程
android
好的佩奇4 小时前
Dart 之类修饰符
android·flutter·dart
alexhilton6 小时前
用Konsist与Lint强制执行设计系统契约
android·kotlin·android jetpack
北京自在科技10 小时前
谷歌安卓 Gemini 迎来界面改版,Find Hub 接入 Gemini 支持物品记忆查找
android·安卓
YB137512 小时前
Jetpack Compose 动画Modifier.animateItem()
android
2401_8858850413 小时前
巴林语音通知接口如何对接?系统告警语音API接入教程
android·前端·网络·python·语音识别
收纳过往13 小时前
数据库加索引的时机:慢查询日志说话
android·开发语言·数据库·python·低代码·rxjava
狂热开发者14 小时前
车载中控要给鸿蒙用户,能不能和 Android 共用一个二维码?
android·华为·harmonyos
.Bryce.15 小时前
T2-LLM评测不等于Agent评测
android·java·人工智能·后端·gpt·agent·1024程序员节
美狐美颜SDK开放平台16 小时前
视频美颜SDK如何应对快速转头与大幅度面部动作?
android·人工智能·ios·音视频·直播美颜sdk·视频美颜sdk