Call static method java jni
Prior to interact, several conceptual look at what used to call:
Find the corresponding class -jclass Find the corresponding method -jmethonID Call the relevant method CallVoidMethid Release related resources on the line
And a signature generation method, Native method, when generating header files are automatically annotated, manually java file signature generation method, as follows:
enter the following command \ app \ \ intermediates under build \ classes directory:
Signature javap -s package name + class name generating method
And c invoke java example method steps:
1, find the corresponding class --findClass 2, and then call its constructor GetMethodID 3, creates its objects NewObject 4, calling its methods
Similarly, the first step to prepare a static method java code layer, examples of methods and fields, a special package jni interface class:
public class MyFirstJni < private String addRess = "beijing"; private static String name = "nata"; static < System.loadLibrary("firstC"); >public static void loadMessage(String data) < Log.d("data", data); >public void method(String data) < loadMessage(data); loadMessage(addRess); >public static void staticMethod(String data) < loadMessage(data); loadMessage(name); >// java jni call public static native String getJniData(); public static native void callStaticMethod(int c); public static native void callStaticMethod(long i,String str); public native void callInstanceMethod(int i); public native void callInstanceMethod(String str,long i); >
Step Two: Generate a header file jni
/* DO NOT EDIT THIS FILE - it is machine generated */ #include /* Header for class com_example_a13940_myapplication_MyFirstJni */ #ifndef _Included_com_example_a13940_myapplication_MyFirstJni #define _Included_com_example_a13940_myapplication_MyFirstJni #ifdef __cplusplus extern "C" < #endif /* * Class: com_example_a13940_myapplication_MyFirstJni * Method: getJniData * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_example_a13940_myapplication_MyFirstJni_getJniData (JNIEnv *, jclass); /* * Class: com_example_a13940_myapplication_MyFirstJni * Method: callStaticMethod * Signature: (I)V */ JNIEXPORT void JNICALL Java_com_example_a13940_myapplication_MyFirstJni_callStaticMethod__I (JNIEnv *, jclass, jint); /* * Class: com_example_a13940_myapplication_MyFirstJni * Method: callStaticMethod * Signature: (JLjava/lang/String;)V */ JNIEXPORT void JNICALL Java_com_example_a13940_myapplication_MyFirstJni_callStaticMethod__JLjava_lang_String_2 (JNIEnv *, jclass, jlong, jstring); /* * Class: com_example_a13940_myapplication_MyFirstJni * Method: callInstanceMethod * Signature: (I)V */ JNIEXPORT void JNICALL Java_com_example_a13940_myapplication_MyFirstJni_callInstanceMethod__I (JNIEnv *, jobject, jint); /* * Class: com_example_a13940_myapplication_MyFirstJni * Method: callInstanceMethod * Signature: (Ljava/lang/String;J)V */ JNIEXPORT void JNICALL Java_com_example_a13940_myapplication_MyFirstJni_callInstanceMethod__Ljava_lang_String_2J (JNIEnv *, jobject, jstring, jlong); #ifdef __cplusplus >#endif #endif
The third step: call java jni method and the method of preparation of the specific implementation cpp file
// // Created by 13940 on 2019/1/1. // #include "com_example_a13940_myapplication_MyFirstJni.h" // java jni call method JNIEXPORT jstring JNICALL Java_com_example_a13940_myapplication_MyFirstJni_getJniData (JNIEnv * env, jclass jcls)< return env->NewStringUTF("FORM C DATA"); > /* * Class: com_example_a13940_myapplication_MyFirstJni * Method: callStaticMethod * Signature: (I)V */ // call static methods and modify the member variables JNIEXPORT void JNICALL Java_com_example_a13940_myapplication_MyFirstJni_callStaticMethod__I (JNIEnv * env, jclass jclassess, jint i)< // find the relevant class Note that the path is not a band with a backslash. jclass cls_First = env->FindClass("com/example/a13940/myapplication/MyFirstJni"); if(cls_First == NULL) < return; >/** Method parameters: class names, method names, method signatures */ // find the corresponding method signature followed by a colon attention jmethodID mtd_static_method = env->GetStaticMethodID(cls_First,"staticMethod","(Ljava/lang/String;)V"); if(mtd_static_method == NULL) < return; >// change the value of java in the static field member variables get attention signature behind colon jfieldID file_name = env->GetStaticFieldID(cls_First,"name","Ljava/lang/String;"); if(file_name == NULL) < return; >// define the value of the static field jstring name = env->NewStringUTF("TOM"); // set the value of the member variable env ->SetStaticObjectField(cls_First,file_name,name); jstring data = env->NewStringUTF("call static method"); if(data == NULL) < return; >// static method call java layer env ->CallStaticVoidMethod(cls_First,mtd_static_method,data); // delete references to env->DeleteLocalRef(cls_First); env->DeleteLocalRef(name); env->DeleteLocalRef(data); > /* * Class: com_example_a13940_myapplication_MyFirstJni * Method: callInstanceMethod * Signature: (I)V */ // call the java instance methods and instance variables modified JNIEXPORT void JNICALL Java_com_example_a13940_myapplication_MyFirstJni_callInstanceMethod__I (JNIEnv *env, jobject jobj, jint i)< // find the corresponding method jclass cls_First = env->FindClass("com/example/a13940/myapplication/MyFirstJni"); if(cls_First == NULL) < return; >// find the corresponding method jmethodID mtd_method = env->GetMethodID(cls_First,"method","(Ljava/lang/String;)V"); if(mtd_method == NULL) < return; >// find the corresponding constructor jmethodID mtd_construct = env->GetMethodID(cls_First,"","()V"); if(mtd_construct == NULL) < return; >jfieldID fld_address = env->GetFieldID(cls_First,"addRess","Ljava/lang/String;"); if(fld_address == NULL) < return; >jstring address = env->NewStringUTF("shanghai"); if(address == NULL) < return; >// Create the appropriate object jobject oFirst = env->NewObject(cls_First,mtd_construct,NULL); if(oFirst == NULL) < return; >// Note that this time the object should be jobject non-target objects jclass env->SetObjectField(oFirst,fld_address,address); jstring message = env->NewStringUTF("call instance method"); // Invoke instance method java layer object should be noted that in this case the non-target jobject objects jclass env->CallVoidMethod(oFirst,mtd_method,message); // clear reference to the object env->DeleteLocalRef(message); env->DeleteLocalRef(cls_First); env->DeleteLocalRef(oFirst); env->DeleteLocalRef(address); >
Step four: Call jni method
new MyFirstJni().callInstanceMethod(2);
MyFirstJni.callStaticMethod(21);
viewById.setText(MyFirstJni.getJniData());
Call static method java jni
Do an experiment for colleagues.
This experiment is java call jni interface, from the jni interface, call the static method in the java class written by yourself, change the value of the static variable in the java class.
This experiment is not for colleagues. After you finish it, throw this first and refer to it later.
Project download point
running result
D:\my_tmp\my_jni_s_call_s\src>echo "run java prj begin, please wait a moment. " "run java prj begin, please wait a moment. " D:\my_tmp\my_jni_s_call_s\src>echo "on \my_jni\src, run below cmd" "on \my_jni\src, run below cmd" D:\my_tmp\my_jni_s_call_s\src>"C:\Program Files\Java\jre1.8.0_161\bin\java.exe" com.my_jni_test.class_my_jni_test * hello my_jni_test.java >> cb_set_value(x) > this->m_l_value_on_java_prj = 111111 0 : dll inside 1 : dll inside 2 : dll inside 3 : dll inside m_l_value_on_java_prj = 2048 D:\my_tmp\my_jni_s_call_s\src>echo "run java prj end :)" "run java prj end :)" D:\my_tmp\my_jni_s_call_s\src>pause Please press any key to continue. . .
You can see that you changed the static variables in your own Java class.
experiment
Java call jni implementation
// @file my_jni_test.java // on linux, javac can't support chinese text // so, if want add comment, please use english text // view this class signature // javap -s libmy_jni_test.so package com.my_jni_test; import com.my_jni_test.class_fun_ret_result; public class class_my_jni_test < // native method on our .so // method must was static // interface for so project static public native String do_task(class_fun_ret_result info_out); static private long m_l_value_on_java_prj; static < // on linux, load .so // on win, load .dll // D:\my_tmp\my_jni_s_call_s\src\my_jni_dll\x64\Debug\my_jni_dll_D.dll System.load("D:\\my_tmp\\my_jni_s_call_s\\src\\my_jni_dll\\x64\\Debug\\my_jni_dll_D.dll"); // must .so load by full path name >public static void main(String[] args) < int i = 0; String str_tmp = ""; m_l_value_on_java_prj = 0; System.out.println("* hello my_jni_test.java"); class_fun_ret_result info_rc = new class_fun_ret_result(); info_rc.str_1 = "123456"; // is pin code give by user System.out.println(">> cb_set_value(x)"); cb_set_value(111111); System.out.println("> this->m_l_value_on_java_prj = " + m_l_value_on_java_prj); do_task(info_rc); System.out.println("m_l_value_on_java_prj = " + m_l_value_on_java_prj); > static public void cb_set_value(long l_in) < m_l_value_on_java_prj = l_in; >>
C++ implementation of jni
// my_jni_dll.cpp : defines the export function of the DLL application. // #include "stdafx.h" #include #include #include #include #include #include "my_jni_dll.h" #include "../com_my_jni_test_class_my_jni_test.h" #define RC_STRING_DEVICE_WAS_OPEN_OK "ok" #define RC_STRING_DEVICE_WAS_OPEN_ERR "err" jstring pChar2JString(JNIEnv* env, const char* pat); char* JString2pChar(JNIEnv* env, jstring jstr); /* * Class: com_my_jni_test_class_my_jni_test * Method: do_task * Signature: (Lcom/my_jni_test/class_fun_ret_result;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_my_1jni_1test_class_1my_1jni_1test_do_1task (JNIEnv * p_env, jclass p_class, jobject p_object) < char sz_buf[4096] = ; char sz_ukey_serial_number[0x100] = ; int i_rc = 0; int i_enable = 0; int i_fault = 0; UINT32 ui_pin_code_retry_cnt = 0; jclass p_jclass_object = NULL; jfieldID p_jfieldID_str_1 = NULL; jfieldID p_jfieldID_str_2 = NULL; jfieldID p_jfieldID_str_3 = NULL; std::string str_pin_code_in = ""; jstring jstr = NULL; do < ::MessageBoxA(NULL, "ls debug", "bp for debug", MB_OK); printf("0 : dll inside\n"); printf("1 : dll inside\n"); jmethodID owner_fun = p_env->GetStaticMethodID(p_class, "cb_set_value", "(J)V"); printf("2 : dll inside\n"); p_env->CallStaticVoidMethod(p_class, owner_fun, 2048L); printf("3 : dll inside\n"); // return string sprintf(sz_buf, "%s", RC_STRING_DEVICE_WAS_OPEN_OK); > while (0); return pChar2JString(p_env, sz_buf); > jstring pChar2JString(JNIEnv* env, const char* pat) < jclass strClass = env->FindClass("Ljava/lang/String;"); jmethodID ctorID = env->GetMethodID(strClass, "", "([BLjava/lang/String;)V"); jbyteArray bytes = env->NewByteArray(strlen(pat)); env->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*)pat); jstring encoding = env->NewStringUTF("utf-8"); return (jstring)env->NewObject(strClass, ctorID, bytes, encoding); > char* JString2pChar(JNIEnv* env, jstring jstr) < char* rtn = NULL; jclass clsstring = env->FindClass("java/lang/String"); jstring strencode = env->NewStringUTF("utf-8"); jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B"); jbyteArray barr= (jbyteArray)env->CallObjectMethod(jstr, mid, strencode); jsize alen = env->GetArrayLength(barr); jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE); if (alen > 0) < rtn = (char*)malloc(alen + 1); memcpy(rtn, ba, alen); rtn[alen] = 0; >env->ReleaseByteArrayElements(barr, ba, 0); return rtn; >
Call static method java jni
1、 Create a new test class TestProvider.java
a) This class is provided 2 Methods
b) a static method , a non-static method
a) Need to put in this file Java Class in TestProvider Map to C in
b) Put TestProvider Two methods are mapped to C in
c) New TestProvider Object
3、 Android upper layer transfer JNI Floor
5、 C Layer call Java method
2 Design implementation
1 The interface design is as follows:
same as usual , Very jealous , But practical ,
The code is not posted here. , Brothers in need can download directly to the end of the article.
C Classes, methods, and objects that define mappings
C Medium mapping class
C New object
jmethodID construction_id = (*jniEnv)->GetMethodID(jniEnv, TestProvider,»», «()V»);
TestProvider mTestProvider = (*jniEnv)->NewObject(jniEnv, TestProvider,construction_id);
C Medium mapping method
getTime = (*jniEnv)-> GetStaticMethodID (jniEnv, TestProvider, «getTime»,»()Ljava/lang/String;»);
sayHello = (*jniEnv)-> GetMethodID (jniEnv, TestProvider, «sayHello»,»(Ljava/lang/String;)V»);
C Called in Java of method
(*jniEnv)-> CallStaticObjectMethod (jniEnv, TestProvider, getTime);
(*jniEnv)-> CallVoidMethod (jniEnv, mTestProvider, sayHello,jstrMSG);
note Get XXX MethodID with Call XXX Method 。
First XXX Represents the type of mapping method, such as: Static Non-static
the second XXX Express Call the return value of the method ,Such as: Void,Object, and many more. (when calling static methods Call Be added later Static )
detailed Mapping method with Call method Please refer to JNI Document ,This is very important !
3、 Java upper layer Key code
TestProvider.Java Two methods
4、 Android.mk file Key code
same as usual , Don’t say it , You know. If you don’t understand , quack , Then please click Android.mk file Introduction
3 ,running result
1 Click “ C transfer java Static method» button
C Successfully called Java middle getTime method , by C Method prints the time of the upper call , And the upper layer successfully toss out the call information.
2 Click “ C transfer java Non-static method» button
C Successfully called sayHello method , And successfully received C Passed parameters, and Toast out corresponding information
4 、 C transfer Java be careful
a) C Mapping java Method time Corresponding signature
getTime = (*jniEnv)->GetStaticMethodID(jniEnv, TestProvider, «getTime», «()Ljava/lang/String;» );
The story has not developed so fast , The next chapter will specifically introduce the use of this signature.
b) Mapping methods need to distinguish between static and non-static GetStaticMethodID,GetMethodID
c) Also need to distinguish when calling CallStaticObjectMethod,CallVoidMethod And also need to distinguish the return value type
If you don’t understand, please leave a message, personal skills are limited, and there are mistakes. Please tell the big cows. , If you are not comprehensive enough, please bear with me, thank you. ,
Click to download the source code C transfer Java example
This article comes fromduickyBlog, reproduced, please indicate the source