++ ++
This article is original on this site. You are welcome to repost it! Reprinted please indicate the source:
Http://blog.csdn.net/mr_raptor/article/details/7401178
++ ++
Create a Java object in local C code
The object used to create the Java domain is to create an instance of the Java class and then call the construction method of the Java class.
Taking the construction of Bitmap as an example, bitmap does not have the code created by Java objects and externally accessible constructor methods, so its instantiation must be implemented in jni c.
Bitmapfactory. Java provides the bitmap method, which simplifies the time sequence:
Bitmapfactory. Java-> bitmapfactory. cpp-> graphicsjni: createbitmap () [graphics. cpp]
Implementation of graphicsjni: createbitmap () [graphics. cpp:
Jobjectgraphicsjni: createbitmap (jnienv * ENV, skbitmap * bitmap, bool ismutable, <br/> jbytearray ninepatch, intdensity) <br/>{ <br/> skassert (Bitmap! = NULL); <br/> skassert (null! = Bitmap-> pixelref (); </P> <p> jobject OBJ = env-> allocobject (gbitmap_class); <br/> If (OBJ) {<br/> env-> callvoidmethod (OBJ, gbitmap_constructormethodid, <br/> (jint) bitmap, ismutable, ninepatch, density ); <br/> If (hasexception (ENV) {<br/> OBJ = NULL; <br/>}< br/> return OBJ; <br/>}
While gbitmap_class is obtained through:
Jclass c = env-> findclass ("android/graphics/bitmap"); <br/> gbitmap_class = (jclass) ENV-> newglobalref (C ); <br/> // gbitmap_constructormethodid is the jmethodid of the bitmap Constructor ("<init>"): <br/> gbitmap_constructormethodid = env-> getmethodid (gbitmap_class, "<init>", <br/> "(IZ [Bi) V ");
To sum up, how to access the attributes of a Java object in C:
1) Find the corresponding jclass through jnienv: findclass;
2) use jnienv: getmethodid () to find the jfieldid of the class constructor;
3) create an object of this class through jnienv: allocobject;
4) Call the Java object constructor through jnienv: callvoidmethod.
Save local JNI objects
Objects generated by a certain call in the C domain are invisible when other functions are called. Although global variables can be set, this is not a good solution, in Android, an int-type variable is usually defined in the Java domain. The object generated in the C domain is associated with the variable in the Java domain, in this variable.
Take jnicameracontext as an example:
Jnicameracontext is the type defined in android_hardware_camera.cpp and generates objects in CPP, which is associated with mnativecontext of Android. Hardware. Camera in Java.
Before registering the native function, C has obtained the jfieldid of the attribute in the Java domain. Use the following methods
Jclass clazz = env-> findclass ("android/hardware/camera"); <br/> jfieldid field = env-> getfieldid (clazz, "mnativecontext", "I ");
If the execution is successful, save the field to the context: jfieldid of the fileds variable in the figure above.
When a CPP object is generated, jnienv: setintfield () is used to set the attributes of the Java object.
Static void android_hardware_camera_native_setup (jnienv * ENV, jobjectthiz, <br/> jobject weak_this, jintcameraid) <br/>{< br/> //... </P> <p> // we use a weak reference sothe camera object can be garbage collected. <br/> // The reference is only used asa proxy for callbacks. <br/> sp <jnicameracontext> context = new jnicameracontext (ENV, weak_this, clazz, camera); <br/> //... <Br/> // use context. get () to get the address of the context object and save it to the mnativecontext attribute in Java <br/> env-> setintfield (thiz, fields. context, (INT) context. get (); <br/>}
To be used, you can use jnienv: getintfield () to obtain the attributes of a Java object and convert it to the jnicameracontext type:
Jnicameracontext * context = reinterpret_cast <jnicameracontext *> (env-> getintfield (thiz, fields. Context); <br/> If (context! = NULL) {<br/> //... <Br/>}
To sum up, how to save and use the objects generated in C ++:
1) Find the corresponding jclass through jnienv: findclass;
2) use jnienv: getfieldid () to find the jfieldid of the attribute in the class;
3) When a CPP object is generated during a call, jnienv: setintfield () is used to set the attribute of the Java object;
4) In addition, the Java object attributes are obtained through jnienv: getintfield () during the call process, and then converted to the real object type.
JNI detailed description: http://mindprod.com/jgloss/jni.html