Compile an android program to call the jni local method (detailed example)

Source: Internet
Author: User

Jni will be used when writing android programs. The following code is about C implementation. For environment configuration, please refer to my other blogs. If you don't talk about it, go directly to the code, almost every sentence in the code will be explained, which is absolutely understandable.

# Include "com_ndk_test_JniClient.h" # include <stdlib. h> // # include <jni. h> # include <stdio. h> # define ARRAY_LENGTH 5 // macro definition # ifdef _ cplusplusextern "C" {# endif/** Class: com_ndk_test_JniClient * Method: AddStr * Signature: (Ljava/lang/String; ljava/lang/String;) Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_com_ndk_test_JniClient_AddStr (JNIEnv * env, jclass arg, jstring a, jstring B) {// JNIEnv is also in jni. set in h The context of the JNI call. // GetStringUTFChars (), ReleaseStringUTFChars (), and NewStringUTF () are both JNIEnv functions. // Jstring str = (* env)-> NewStringUTF (env, "HelloWorld from JNI! "); // Obtain the UTF-encoded input character from the JNI call context and place it in the memory segment pointed to by the pointer 'str'. const char * str = (* env) -> GetStringUTFChars (env, a, 0); // This is the c writing method, followed by c writing // const char * s1 = env-> GetStringUTFChars (, 0); // This is the c ++ writing method. The following methods are in the form of char cap [128]; // defines the char array strcpy (cap, str ); // copy the string to cap (* env)-> ReleaseStringUTFChars (env, a, str); // release the memory, I personally think this is like the c ++ virtual function int I = 0; for (I = 0; I <strlen (cap); I ++) * (cap + I) = (char) toupper (* (cap + I ));/ /Return the string converted in uppercase (* env)-> NewStringUTF (env, cap ); // string pointer in C language to JNI jstring type // return (* env)-> NewStringUTF (env, strupr (cap); // return str ;} /** Class: com_ndk_test_JniClient * Method: AddInt * Signature: (II) I */JNIEXPORT jint JNICALL struct (JNIEnv * env, jclass arg, jint a, jint B) {return a + B ;}; // TODOJNIEXPORT jint JNICALL Java_com_ndk_test_JniClient_intArrayMet Hord (JNIEnv * env, jclass clazz, jintArray array) {// return 200; int I, sum = 0; jsize len = (* env)-> GetArrayLength (env, array); jint * body = (* env)-> GetIntArrayElements (env, array, 0); for (I = 0; I <len; I ++) {sum + = body [I];} (* env)-> ReleaseIntArrayElements (env, array, body, 0); return sum;} JNIEXPORT jboolean JNICALL values (JNIEnv * env, jclass clazz, jboolean B) {r Eturn B;}/*** the following code must be declared in the java program, and the header file is not rewritten **/JNIEXPORT jintArray JNICALL Java_com_ndk_test_JniClient_intMethord (JNIEnv * env, jclass clazz) {int I = 1; // jint is the integer type jintArray array exists in the JNI frame; // defines the array object array = (* env)-> NewIntArray (env, 10); // open up a jint array with a length of 10 for (; I <= 10; I ++) // Add the element 1-10 (* env)-> SetIntArrayRegion (env, array, I-1, 1, & I) to the array in sequence; // demonstrate GetArrayLength () and GetIntArrayElements (). Method/* obtain the number of elements of the array object */int len = (* env)-> GetArrayLength (env, array ); /* obtain all elements in the array */jint * elems = (* env)-> GetIntArrayElements (env, array, 0); for (I = 0; I <len; I ++) printf ("ELEMENT % d IS % d/n", I, elems [I]); return array ;} /*** the first parameter of all local methods points to the JNIEnv structure. * This structure is used to call the JNI function. The meaning of the second jclass parameter * depends on whether the method is static or Instance. * In the former, jclass indicates the reference of a class object, while in the latter, it indicates the reference of the object to which the called method belongs. * Deepening: although the array is still transmitted, the base class of the array is replaced with an object data type such as string. * The Java program will pass in a string containing Chinese characters to the C program. * The C program does not process this string, but opens a new string array and returns it to the Java program, it also contains two Chinese character strings. * Java writing ----->: public native String [] stringMethod (String text); public static void main (String [] args) throws java. io. unsupportedEncodingException {System. loadLibrary ("Sample3"); Sample3 sample = new Sample3 (); String [] texts = sample. stringMethod ("java programming ideology"); for (int I = 0; I <texts. length; I ++) {texts [I] = new String (texts [I]. getBytes ("ISO8859-1"), "GBK"); System. out. print (texts [I]);} System. out. Println ();} **/JNIEXPORT jobjectArray JNICALL inline (JNIEnv * env, jclass obj, jstring string) {// use the FindClass () function to obtain java in the JNI context. lang. string type, and assign it to the jclass variable jclass objClass = (* env)-> FindClass (env, "java/lang/String "); // The JNI framework does not define a special string array, // instead, it uses jobjectArray -- Object array. // The base class of the object array is jclass, and jclass is the unique type of the JNI framework, // equivalent to the Class type in Java. // defines an array of 5 objects, textsjobjectArray. Texts = (* env)-> NewObjectArray (env, (jsize) ARRAY_LENGTH, objClass, 0); jstring jstr; char * sa [] = {"Hello,", "world! "," JNI "," very "," fun "}; int I = 0; // loop into the string in the pre-defined sa array, // Of course, the precondition is to use the NewStringUTF () function to convert the C language string to the jstring type for (; I <ARRAY_LENGTH; I ++) {jstr = (* env) -> NewStringUTF (env, sa [I]); (* env)-> SetObjectArrayElement (env, texts, I, jstr ); // jstring must be included} // Chinese characters are input using the GBK-supported input method, while the Java program uses the ISO8859_1 character set to store return texts, which is called by JNI ;} /*** it demonstrates that the C program transmits an object array to the Java program, * and the object array is no longer a string, * It is a custom MailInfo object type in Java that contains a topic attribute * Ma The ilInfo object is defined as follows:-> public class MailInfo {public String topic; public String getTopic () {return this. topic;} public void setTopic (String topic) {this. topic = topic;} the source code of the Java program is as follows:-> public class Sample4 {public native MailInfo [] objectMethod (String text); public static void main (String [] args) {System. loadLibrary ("Sample4"); Sample4 sample = new Sample4 (); MailInfo [] mails = sample. objectMetho D ("Thinking In Java"); for (int I = 0; I <mails. length; I ++) System. out. println (mails [I]. topic) ;}}**/JNIEXPORT jboolean JNICALL Java_com_ndk_test_JniClient_objectMethod (JNIEnv * env, jobject obj, jstring string) {// use FindClass () in the JNI context, the function obtains java. lang. object Type (Class), // and use it as the base Class to open up an array of objects with a length of 5 (# define ARRAY_LENGTH 5), ready to store MailInfo objects. Class objClass = (* env)-> FindClass (env, "java/lang/Object"); jobjectArray mails = (* env)-> NewObjectArray (env, (jsize) ARRAY_LENGTH, objClass, 0); jclass objectClass = (* env)-> FindClass (env, "MailInfo"); // create a jfieldID variable. In JNI, the operation object attributes are all performed through jfieldID. // first find the type (Class) of MailInfo, // based on this jclass, further obtain its topic attribute and assign it to the jfieldID variable. JfieldID topicFieldId = (* env)-> GetFieldID (env, objectClass, "topic", "Ljava/lang/String;"); int I = 0; // cyclically Insert the jobject object into the object array. The SetObjectField () function is used for the first time. // This function is used to assign values to the jobject attribute, and the value content is the jstring variable value passed in by the Java program. // Note that when assigning values to object attributes and placing objects in the object array, // we use the jobject type environment parameter obj defined in the function header as the intermediary. // At this point, the two inherent environment input parameters env and obj of the JNI frame are involved. For (; I <ARRAY_LENGTH; I ++) {(* env)-> SetObjectField (env, obj, topicFieldId, string); (* env)-> SetObjectArrayElement (env, mails, I, obj);} return mails ;}# ifdef _ cplusplus} # endif

package com.ndk.test;public class JniClient {static {System.loadLibrary("TestNdk");}private JniClient() {}private static JniClient jniClient = new JniClient();public static JniClient getInstance() {return jniClient;}public native String AddStr(String strA, String strB);public native int AddInt(int a, int b);// ==============public native int intArrayMethord(int[] intArray);public native boolean booleanMethord(boolean b);}



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.