转自:http://daimajishu.iteye.com/blog/1085167
几个与内存相关的类的头文件如下所示:
IMemory.h :定义内存相关类的接口,表示堆内存的类 IMemoryHeap 和 BnMemoryHeap ,表示一般内存的类IMemory 和 BnMemory 。
MemoryHeapBase.h :定义类 MemoryHeapBase ,继承并实现 BnMemoryHeap
MemoryBase.h :定义类 MemoryBase ,继承并实现 BnMemory
在一般的使用过程中,通常是以使用 MemoryHeapBase 类分配一块堆内存(类似 malloc ),而 MemoryBase 表示从一块分配好堆内存中的一部分内存。
class AudioTrackJniStorage {
public:
sp<MemoryHeapBase> mMemHeap;// 这两个Memory 很重要
sp<MemoryBase> mMemBase;
audiotrack_callback_cookie mCallbackData;
int mStreamType;
bool allocSharedMem(int sizeInBytes) {
mMemHeap = new MemoryHeapBase(sizeInBytes, 0, "AudioTrack Heap Base");
mMemBase = new MemoryBase(mMemHeap, 0, sizeInBytes);
// 注意用法,先弄一个HeapBase ,再把HeapBase 传入到MemoryBase 中去。
return true;
}
};
2 MemoryHeapBase
MemroyHeapBase 也是 Android 搞的一套基于 Binder 机制的对内存操作的类。既然是 Binder 机制,那么肯定有一个服务端( Bnxxx ),一个代理端 Bpxxx 。看看 MemoryHeapBase 定义:
class MemoryHeapBase : public virtual BnMemoryHeap
{
果然,从BnMemoryHeap 派生,那就是Bn 端。这样就和Binder 挂上钩了
//Bp 端调用的函数最终都会调到Bn 这来
对Binder 机制不了解的,可以参考:
http://blog.csdn.net/Innost/archive/2011/01/08/6124685.aspx
有好几个构造函数,我们看看我们使用的:
MemoryHeapBase::MemoryHeapBase(size_t size, uint32_t flags, char const * name)
: mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
mDevice(0), mNeedUnmap(false)
{
const size_t pagesize = getpagesize();
size = ((size + pagesize-1) & ~(pagesize-1));
// 创建共享内存,ashmem_create_region 这个是系统提供的, 可以不管它
// 设备上打开的是/dev/ashmem 设备,而Host 上打开的是一个tmp 文件
int fd = ashmem_create_region(name == NULL ? "MemoryHeapBase" : name, size);
mapfd(fd, size);// 把刚才那个fd 通过mmap 方式得到一块内存
// 不明白得去man mmap 看看
mapfd 完了后,mBase 变量指向内存的起始位置, mSize 是分配的内存大小,mFd 是
ashmem_create_region 返回的文件描述符
}
MemoryHeapBase 提供了一下几个函数,可以获取共享内存的大小和位置。
getBaseID()---> 返回mFd ,如果为负数,表明刚才创建共享内存失败了
getBase()-> 返回mBase ,内存位置
getSize()-> 返回mSize ,内存大小
有了 MemoryHeapBase ,又搞了一个 MemoryBase ,这又是一个和 Binder 机制挂钩的类。
唉,这个估计是一个在MemoryHeapBase 上的方便类吧?因为我看见了offset
那么估计这个类就是一个能返回当前Buffer 中写位置(就是offset )的方便类
这样就不用用户到处去计算读写位置了。