1. nativePtr作用 
Java层:nativePtr long类型的 保存 C++ 对象指针的地址 
C++层:nativePtr —> C++ 对象 
 
1.1 理解源码中nativePtr 在openCV中有个Mat.java ,Mat.cpp(Java_org_opencv_core_Mat_n_1Mat__DDI) 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public  class  Mat      public  final  long  nativeObj;     public  Mat (long  addr)           if  (addr == 0 )             throw  new  UnsupportedOperationException("Native object address is NULL" );         nativeObj = addr;     }          public  Mat ()           nativeObj = n_Mat();     }                   private  static  native  long  n_Mat ()           private  static  native  long  n_Mat (int  rows, int  cols, int  type)  } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1Mat__DDI   (JNIEnv* env, jclass, jdouble size_width, jdouble size_height, jint type); JNIEXPORT jlong JNICALL Java_org_opencv_core_Mat_n_1Mat__DDI   (JNIEnv* env, jclass, jdouble size_width, jdouble size_height, jint type) {     static  const  char  method_name[] = "Mat::n_1Mat__DDI()" ;     try  {         LOGD("%s" , method_name);         Size size ((int )size_width, (int )size_height)  ;                           return  (jlong) new  Mat( size, type );      } catch (const  std ::exception &e) {         throwJavaException(env, &e, method_name);     } catch  (...) {         throwJavaException(env, 0 , method_name);     }     return  0 ; } 
结论: Java层拿到nativeObj就是 Native层C++对象的指针,也就是对象的首地址,下次想去使用Native层的功能时,就可以使用首地址寻找C++对象,并让他干活即可。
2. Parcel源码分析 2.1 Parcel初始化流程 java端初始化 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package  android.os;public  final  class  Parcel           public  static  Parcel obtain ()           final  Parcel[] pool = sOwnedPool;         synchronized  (pool) {             Parcel p;             for  (int  i=0 ; i<POOL_SIZE; i++) {                 p = pool[i];                 if  (p != null ) {                     pool[i] = null ;                     if  (DEBUG_RECYCLE) {                         p.mStack = new  RuntimeException();                     }                     p.mReadWriteHelper = ReadWriteHelper.DEFAULT;                     return  p;                 }             }         }                  return  new  Parcel(0 );     } } 
1 2 3 4 5 6 7 8 9 private  Parcel (long  nativePtr)  	if  (DEBUG_RECYCLE) { 		mStack = new  RuntimeException(); 	} 	 	 	init(nativePtr); } 
1 2 3 4 5 6 7 8 9 10 11 private  void  init (long  nativePtr)  	if  (nativePtr != 0 ) { 		mNativePtr = nativePtr; 		mOwnsNativeParcelObject = false ; 	} else  { 		mNativePtr = nativeCreate();  		mOwnsNativeParcelObject = true ; 	} } private  static  native  long  nativeCreate () 
native代码 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 static  const  JNINativeMethod gParcelMethods[] = {         ......     {"openFileDescriptor" ,        "(Ljava/lang/String;I)Ljava/io/FileDescriptor;" , (void *)android_os_Parcel_openFileDescriptor},     {"dupFileDescriptor" ,         "(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;" , (void *)android_os_Parcel_dupFileDescriptor},     {"closeFileDescriptor" ,       "(Ljava/io/FileDescriptor;)V" , (void *)android_os_Parcel_closeFileDescriptor},          {"nativeCreate" ,              "()J" , (void *)android_os_Parcel_create},     {"nativeFreeBuffer" ,          "(J)J" , (void *)android_os_Parcel_freeBuffer},     {"nativeDestroy" ,             "(J)V" , (void *)android_os_Parcel_destroy},     ...... }; 
1 2 3 4 5 6 7 8 static  jlong android_os_Parcel_create (JNIEnv* env, jclass clazz)          Parcel* parcel = new  Parcel();          return  reinterpret_cast <jlong>(parcel); } 
2.2 写数据 Parcel.java 
1 2 3 4 5 6 7 8 9 10 11 12    public  final  void  writeInt (int  val)                  nativeWriteInt(mNativePtr, val);    } @FastNative     private  static  native  void  nativeWriteInt (long  nativePtr, int  val)  
android_os_Parcel.cpp 的 nativeWriteInt: 
1 2 3 4 5 6 7 8 9 10 11 {"nativeWriteByteArray" ,      "(J[BII)V" , (void *)android_os_Parcel_writeByteArray},   {"nativeWriteBlob" ,           "(J[BII)V" , (void *)android_os_Parcel_writeBlob},         {"nativeWriteInt" ,            "(JI)V" , (void *)android_os_Parcel_writeInt},      {"nativeWriteLong" ,           "(JJ)V" , (void *)android_os_Parcel_writeLong},      {"nativeWriteFloat" ,          "(JF)V" , (void *)android_os_Parcel_writeFloat}, 
实现函数android_os_Parcel_writeInt  :
1 2 3 4 5 6 7 8 9 10 11 12 13 static  void  android_os_Parcel_writeInt (JNIEnv* env, jclass clazz, jlong nativePtr, jint val)           Parcel* parcel = reinterpret_cast <Parcel*>(nativePtr);     if  (parcel != NULL ) {                  const  status_t  err = parcel->writeInt32(val);          if  (err != NO_ERROR) {                          signalExceptionForError(env, clazz, err);         }     } } 
Parcel.cpp 的 writeInt32: 
1 2 3 status_t  Parcel::writeInt32 (int32_t  val)     return  writeAligned(val); } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 template <class  T >status_t  Parcel::writeAligned (T val)      COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof (T)) == sizeof (T));                    if  ((mDataPos+sizeof (val)) <= mDataCapacity) {                           restart_write: *reinterpret_cast <T*>(mData+mDataPos) = val;                  return  finishWrite(sizeof (val));     }     status_t  err = growData(sizeof (val));     if  (err == NO_ERROR) goto  restart_write;     return  err; } 
finsihWrite函数: 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 status_t  Parcel::finishWrite (size_t  len)      if  (len > INT32_MAX) {                           return  BAD_VALUE;     }          mDataPos += len;      ALOGV("finishWrite Setting data pos of %p to %zu" , this , mDataPos);     if  (mDataPos > mDataSize) {         mDataSize = mDataPos;         ALOGV("finishWrite Setting data size of %p to %zu" , this , mDataSize);     }          return  NO_ERROR; } 
读的流程是一样的,按照顺序一个类型一个类型读出来。最核心的思想就是共享内存写数据和读数据。
2.3 CMakeList配置导入全部.cpp 1 2 3 4 5 6 file(GLOB allSource *.c *.cpp) add_library( 	native-lib 	SHARED 	${allSource} ) 
3. 自定义Parcelable 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 public  class  Student  implements  Parcelable      protected  Student (Parcel in)           in.readInt();          in.readString();     }     @Override      public  void  writeToParcel (Parcel dest, int  flags)           dest.writeInt(10 );          dest.writeString("AAA" );     }     @Override      public  int  describeContents ()           return  0 ;     }     public  static  final  Creator<Student> CREATOR = new  Creator<Student>() {         @Override          public  Student createFromParcel (Parcel in)               return  new  Student(in);         }         @Override          public  Student[] newArray(int  size) {             return  new  Student[size];         }     }; } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public  class  MainActivity  extends  AppCompatActivity      @Override      protected  void  onCreate (Bundle savedInstanceState)           super .onCreate(savedInstanceState);         setContentView(R.layout.activity_main);                  Parcel parcel = Parcel.obtain();         parcel.writeInt(50 );         parcel.writeInt(100 );                           parcel.setDataPosition(0 );          int  r = parcel.readInt();         Log.d("Jack" , "onCreate: 系统的:"  + r);         r = parcel.readInt();         Log.d("Jack" , "onCreate: 系统的:"  + r);     } } 
4.Parcelable为什么比Serializable高效 Serializable IO流完成的(存储到磁盘),   Parcelable C++ 对象指针 共享内存 指针挪动报错数据。
版权声明:  此文章版权归Jack Ou所有,如有转载,请註明来自原作者