要实现类似Parcel的内存共享,其思路为通过jni在cpp层创建对象,将该对象的指针地址保存到java层,然后通过native方法去操作该块内存。
Java层定义的Parcel:
class Parcel {
private var mNativePtr:Long = 0
init {
System.loadLibrary("native-lib")
mNativePtr = nativeCreate()
}
fun writeInt(value:Int){
nativeWriteInt(mNativePtr,value)
}
fun readInt():Int {
return nativeReadInt(mNativePtr)
}
fun setDatePosition(dataPos: Int){
nativeSetDatePosition(mNativePtr,dataPos)
}
fun recycle(){
nativeRecycle(mNativePtr)
}
private external fun nativeCreate():Long
private external fun nativeWriteInt(mNativePtr:Long,value:Int)
private external fun nativeSetDatePosition(mNativePtr:Long,dataPos:Int)
private external fun nativeReadInt(mNativePtr:Long):Int
private external fun nativeRecycle(mNativePtr:Long)
}
对应Cpp的类:
class Parcel{
char* mData; //共享内存首地址
int mDataPos;
public:
Parcel(){
mDataPos =0;
mData = (char*)malloc(1024);
}
~Parcel(){
free(mData);
}
void writeInt(jint value){
*reinterpret_cast<int*>(mData+mDataPos) =value;
mDataPos += sizeof(int);
}
void setDataPosition(jint value){
mDataPos = value;
}
jint readInt(){
int result =*reinterpret_cast<int*>(mData+mDataPos);
mDataPos += sizeof(int);
return result;
}
};
JNI中实现的native方法:
extern "C" JNIEXPORT jlong JNICALL
Java_com_melrose_jni_Parcel_nativeCreate(
JNIEnv *env,
jobject jobject) {
Parcel * p = new Parcel();
return (jlong)p;
}
extern "C" JNIEXPORT void JNICALL
Java_com_melrose_jni_Parcel_nativeWriteInt(
JNIEnv *env,
jobject jobject,jlong ptr,jint value) {
Parcel * p = reinterpret_cast<Parcel *>(ptr);
p->writeInt(value);
}
extern "C" JNIEXPORT void JNICALL
Java_com_melrose_jni_Parcel_nativeSetDatePosition(
JNIEnv *env,
jobject jobject,jlong ptr,jint pos) {
Parcel * p = reinterpret_cast<Parcel *>(ptr);
p->setDataPosition(pos);
}
extern "C" JNIEXPORT jint JNICALL
Java_com_melrose_jni_Parcel_nativeReadInt(
JNIEnv *env,
jobject jobject,jlong ptr) {
Parcel * p = reinterpret_cast<Parcel *>(ptr);
return p->readInt();
}
extern "C" JNIEXPORT void JNICALL
Java_com_melrose_jni_Parcel_nativeRecycle(
JNIEnv *env,
jobject jobject,jlong ptr) {
Parcel * p = reinterpret_cast<Parcel *>(ptr);
delete(p);
}
在java层写入并读取:
val p =Parcel()
p.writeInt(99)
p.writeInt(88)
p.setDatePosition(0)
val v1 = p.readInt()
val v2 = p.readInt()
Log.d(TAG,"read value1:<span class="katex math inline">v1")
Log.d(TAG,"read value2:</span>v2")
p.recycle()
上面打印的Log分别为99和88;