Learn about JNI in Android (four) simple sample, warm and new

Source: Internet
Author: User

After the 0th article simply introduces the pattern of JNI programming. In the next two or three articles, we have made some simple introductions to some of the concepts in JNI, and I do not know what I have said clearly. But I believe very many children heel me the same. When you start learning something, the best way to get started is to take a ready-made sample to study and learn the concepts. Come back to study the code, deepen the impression, and begin to grasp slowly.

Today we're going to do a little demo. This sample is slightly more complicated than before. However, if you read the previous articles, it is still very easy to understand.

There are so many things. It was horrible when it was unknown. It's easy to understand.

1) We first define a Java class that includes several native methods, such as the following:

public class Paramtransfertest {public static int testval = 1;public native void Changetestval ();p ublic native int add (int x, int y);p ublic native string AddTail (string tail);p ublic native int[] Changearray (int[] arr);}

2) Use the Javah tool to generate the corresponding header file. For example, the following:

/* Don't EDIT this file-it are machine generated */#include <jni.h>/* Header for class Com_lms_jni_paramtransferte St */#ifndef _included_com_lms_jni_paramtransfertest#define _included_com_lms_jni_paramtransfertest#ifdef __ Cplusplusextern "C" {#endif/* * class:com_lms_jni_paramtransfertest * method:changetestval * Signature: () V */jni EXPORT void Jnicall java_com_lms_jni_paramtransfertest_changetestval (jnienv *, jobject); */* Class:com_lms_jni_para  Mtransfertest * Method:add * Signature: (II) I */jniexport jint jnicall java_com_lms_jni_paramtransfertest_add (JNIENV *, Jobject, Jint, jint);/* * class:com_lms_jni_paramtransfertest * method:addtail * Signature: (Ljava/lang/strin g;) ljava/lang/string; */jniexport jstring jnicall java_com_lms_jni_paramtransfertest_addtail (jnienv *, Jobject, jstring);/* * class:com_l Ms_jni_paramtransfertest * Method:changearray * Signature: ([i) [i */jniexport Jintarray jnicall java_com_lms_jni_param Transfertest_chaNgearray (JNIEnv *, Jobject, jintarray); #ifdef __cplusplus} #endif #endif 

The corresponding method is generated above, we can see the previous article described the method name begins with Java, method signature and other information. Right.

3) write C file. For example, the following:

#include <stdio.h> #include <stdlib.h> #include "com_lms_jni_paramtransfertest.h" #include <android/ log.h> #include <jni.h> #include <malloc.h> #define LOG_TAG "System.out" #define LOGD (...) __android_log_ Print (Android_log_debug, Log_tag, __va_args__) #define Logi (...) __android_log_print (Android_log_info, Log_tag, __VA_ args__) char* jstring2cstr (jnienv * env, jstring str) {char * Rtn = Null;jclass clsstring = (*env)->findclass (env, "java/ Lang/string "),//Findclass method to obtain Java String class jstring Strencode = (*env)->newstringutf (env," UTF-8 ");// Call the Newstringutf method, get the "UTF-8" string, as encoded jmethodid mid = (*env)->getmethodid (env, clsstring, "GetBytes", "(ljava/lang/ string;) [B];//Get the GetBytes method of the String class Jbytearray Barr = (Jbytearray) (*env)->callobjectmethod (env, str, MID, Strencode);//Call the GetBytes method of the String class jsize Alen = (*env)->getarraylength (env, Barr);//Get array length jbyte* BA = (*env) Getbytearrayelements (env, Barr, Jni_false);//Get the first address of the array. The first element of an array in C/s + + is a pointer if (Alen > 0) {RTN = (char*) malloc (alen + 1); memcpy (RTN, BA, Alen); Rtn[alen] = 0;} The above step is to copy the values of the array into an array of char*, which is the char array of C + +. Because C + + does not have a string concept, finally ends with 0. (*env)->releasebytearrayelements (env, Barr, BA, 0);//release memory return RTN;} /* * Class:com_lms_jni_paramtransfertest * method:changetestval * Signature: () V */jniexport void Jnicall Java_co M_lms_jni_paramtransfertest_changetestval (JNIENV * env, Jobject obj) {jclass clazz = (*env)->getobjectclass (env,obj );//Obtain the corresponding class for obj. That is paramtransfertestjint val = (*env)->getstaticintfield (env, Clazz, (*env)->getstaticfieldid (env, Clazz, " TestVal "," I "));//Gets the value of the field TestVal Logi (" before change testval =%d ", val);//joins the log information val = val + 1; Logi ("After change testval =%d", val);(*env)->setstaticintfield (env, Clazz, (*env)->getstaticfieldid (env, Clazz , "TestVal", "I"), Val);//Set the value of the field testval}/* * class:com_lms_jni_paramtransfertest * method:add * Signature: (II) I */j Niexport jint jnicall java_com_lms_jni_paramtransfertest_add (jnienv * env, Jobject obj, Jint x, JintY) {Logi ("x =%d", x);       Logi ("y =%d", y); return x + y; return parameters x and y and}/* * class:com_lms_jni_paramtransfertest * method:addtail * Signature: (ljava/lang/string;) Ljava/lang /string;  */jniexport jstring jnicall java_com_lms_jni_paramtransfertest_addtail (jnienv * env, jobject obj, jstring str) {char* p = Jstring2cstr (ENV,STR);//Converts a string in Java into a char array logi ("str =%s", p) in C/A + +, char* newstr = "Tail"; return (*ENV) Newstringutf (env, strcat (P, newstr));//Call the STRCAT function to concatenate two char arrays, which will be returned through NEWSTRINGUTF. }/* * class:com_lms_jni_paramtransfertest * Method:changearray * Signature: ([i) [I */jniexport Jintarray JNICALL Java_com_lms_jni_paramtransfertest_changearray (JNIENV * env, jobject obj, Jintarray ja) {int len = (*env)->getarrayle Ngth (env, JA);/gets the array length logi ("Len =%d", Len); Logi ("address =% #x", &ja); jint* arr = (*env)->getintarrayelements (env, JA, 0);//Deposit all elements of the array in jint* In an array of the first address (array name) int i = 0;for (; i < Len; i++) {Logi ("arr[%d] =%d", I, * (arr + i)); * (arr + i) + =10;} The value of each element in the array plus 10return ja; Since the last parameter of getintarrayelements is 0, it indicates that the obtained array is not copied. That is, they manipulate the same piece of memory, so which array returns the OK return ja;


Corresponding to these four methods, in the above are added some gaze. Everyone looked at the gaze. Take a look at the logic yourself. It is also clear how these several methods implement the function is very easy.

4) Write the android.mk file, for example:

Local_path: = $ (call My-dir) include $ (clear_vars) Local_module: = com_lms_jni_hwdemolocal_src_files: = hwdemo.c jnitest.c Paramtransfertest.clocal_ldlibs + =-lloginclude $ (build_shared_library)

One thing to note here is that when compiling multiple files, the backslash "\" is used to break lines and differentiate between C/s + + files.

And here Local_ldlibs is the dynamic packet that the JNI uses log to add. The next article will say.

5) After writing the android.mk file, compile it with the Ndk-build file. The file structure is as follows:

watermark/2/text/ahr0cdovl2jsb2cuy3nkbi5uzxqvbglubwlhbnnozw5n/font/5a6l5l2t/fontsize/400/fill/i0jbqkfcma==/ Dissolve/70/gravity/center ">


Execute the Ndk-build under the Jni folder, for example the following:


Here, the implementation of the JNI layer is a matter of fact. Here's what's on the Java side.

6) Call in activity, for example the following:

public class Hwdemo extends Activity {static {system.loadlibrary ("Com_lms_jni_hwdemo");//Load Dynamic package, The name is the module name in Android.mk. }public native String Printhello (), @Overridepublic void OnCreate (Bundle savedinstancestate) {super.oncreate ( Savedinstancestate); Setcontentview (R.layout.main); TextView Tvadd = (TextView) Findviewbyid (R.id.tvadd); TextView tvstring = (TextView) Findviewbyid (r.id.tvstring); TextView Tvarray = (TextView) Findviewbyid (R.id.tvarray); TextView tvchangetestval = (TextView) Findviewbyid (r.id.tvchangetestval); Paramtransfertest PTT = new Paramtransfertest ();//Call Changetestva () method Ptt.changetestval (); Tvchangetestval.settext ("" + ptt.testval);//Call the Add method int sum = Ptt.add (1, 2); Tvadd.settext (string.valueof (sum));//Call AddTail method Tvstring.settext ( Ptt.addtail ("LMS"));//Call Changearray method int[] NewArr = Ptt.changearray (New int[]{1,2}); StringBuilder sb = new StringBuilder (); Sb.append ("["); Sb.append (Newarr[0]). Append (","). Append (Newarr[1]); sb.append ("]"); Tvarray.settext (sb.tostring ());}}

7) The results show:

On the assumption that the Java layer calls the Jni method, there is a method of invoking Java in the JNI layer, and manipulating the Java object, I believe that after this example, and then combined with the previous articles, we should be able to the role of JNI and the application has a comparative understanding of the main.

The implementation of the underlying framework in Android, especially when booting up, native layer to load a system core service, or launch zygote virtual machine, the use of a large number of JNI level framework. Let's assume that you're familiar with JNI, and then get to know what these frameworks are. will be very helpful.

End.

Learn about JNI in Android (four) simple sample, warm and new

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.