理論基礎
android系統在應用程式框架層中提供了兩個C++類MemoryHeapBase和MemoryBase來創建和管理匿名共享記憶體,
如果一個行程需要與其他行程共享一塊完整的匿名共享記憶體,那么就可以通過使用MemoryHeapBase類類創建這塊匿名共享記憶體,如果一個行程創建一塊匿名共享記憶體后,只希望與其他行程共享其中的一部分,那么就可以通過MemoryBase類來創建這塊匿名共享記憶體,
IMemory.h:定義記憶體相關類的介面,表示堆記憶體的類IMemoryHeap和BnMemoryHeap,表示一般記憶體的類IMemory和BnMemory,
MemoryHeapBase.h:定義類MemoryHeapBase,繼承并實作BnMemoryHeap
MemoryBase.h:定義類MemoryBase,繼承并實作BnMemory,
android系統在應用程式框架層中提供了java類MemoryFile來創建和管理匿名共享記憶體,使用java類MemoryFile創建的匿名共享記憶體可以在不同的Android應用程式之間進行共享,
java代碼決議
匿名共享記憶體java類MemoryFile在系統中的source\frameworks\base\core\java\android\os\MemoryFile.java檔案中實作,
//匿名共享記憶體的建構式,引數1表示創建匿名共享記憶體的名稱,引數2表示創建匿名共享記憶體大小
public MemoryFile(String name, int length) throws IOException {
mLength = length;
if (length >= 0) {
//通過呼叫jni的介面去打開匿名共享記憶體
mFD = native_open(name, length);
} else {
throw new IOException("Invalid length: " + length);
}
if (length > 0) {
//進行映射
mAddress = native_mmap(mFD, length, PROT_READ | PROT_WRITE);
} else {
mAddress = 0;
}
}
C++關鍵函式決議
//MemoryHeapBase建構式的實作
MemoryHeapBase::MemoryHeapBase(const char* device, size_t size, uint32_t flags)
: mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
mDevice(0), mNeedUnmap(false), mOffset(0)
{
int open_flags = O_RDWR;
if (flags & NO_CACHING)
open_flags |= O_SYNC;
//通過呼叫open打開匿名共享記憶體設備檔案
int fd = open(device, open_flags);
ALOGE_IF(fd<0, "error opening %s: %s", device, strerror(errno));
if (fd >= 0) {
//指定的匿名共享記憶體大小按頁對齊
const size_t pagesize = getpagesize();
size = ((size + pagesize-1) & ~(pagesize-1));
//匿名共享記憶體映射到當前行程地址空間
if (mapfd(fd, size) == NO_ERROR) {
mDevice = device;
}
}
}
//MemoryHeapBase建構式
MemoryHeapBase::MemoryHeapBase(size_t size, uint32_t flags, char const * name)
: mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags),
mDevice(0), mNeedUnmap(false), mOffset(0)
{
//獲得系統中頁大小的記憶體
const size_t pagesize = getpagesize();
//記憶體頁對齊
size = ((size + pagesize-1) & ~(pagesize-1));
//創建一塊匿名共享記憶體
int fd = ashmem_create_region(name == NULL ? "MemoryHeapBase" : name, size);
ALOGE_IF(fd<0, "error creating ashmem region: %s", strerror(errno));
if (fd >= 0) {
//創建的匿名共享記憶體映射到當前行程地址空間中
if (mapfd(fd, size) == NO_ERROR) {
if (flags & READ_ONLY) {//如果地址映射成功,修改匿名共享記憶體的訪問屬性
ashmem_set_prot_region(fd, PROT_READ);
}
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/294974.html
標籤:其他
