JNI Learning Note 2-java passed to the C-C code to logcat output content-C code callback Java method

Source: Internet
Author: User

Java passes the data to the C example:

public class JNI {

static{
System.loadlibrary ("PassData");
}

Pass two variables of type int to C let C add a second to return
public native int Add (int x, int y);
Pass arguments of type string to C and return to
Public native string Sayhelloinc (string s);
Passing an array of type int to C
Public native int[] Arrelementsincrease (int[] intarray);
}

Written in the C language:

#include <jni.h>
#include <stdlib.h>

#include <android/log.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__)

Jniexport Jint Jnicall Java_com_itheima_javapassdata_jni_add
(JNIENV * env, Jobject Clazz, Jint x, Jint y) {
return x+y;
}

/**
* Converts a jstring into a C-language char* type.
*/
char* _jstring2cstr (jnienv* env, jstring jstr) {
char* rtn = NULL;
Jclass clsstring = (*env)->findclass (env, "java/lang/string");
Jstring Strencode = (*env)->newstringutf (env, "GB2312");
Jmethodid mid = (*env)->getmethodid (env, clsstring, "GetBytes", "(ljava/lang/string;) [B");
Jbytearray Barr = (Jbytearray) (*env)->callobjectmethod (env, JSTR, Mid, Strencode); String. GetByte ("GB2312");
Jsize alen = (*env)->getarraylength (env, Barr);
jbyte* ba = (*env)->getbytearrayelements (env, Barr, Jni_false);
if (Alen > 0) {
Rtn = (char*) malloc (alen+1);//"+"
memcpy (RTN, BA, Alen);
rtn[alen]=0;
}
(*env)->releasebytearrayelements (env, Barr, ba,0);
return RTN;
}

Jniexport jstring Jnicall Java_com_itheima_javapassdata_jni_sayhelloinc
(JNIENV * env, Jobject clazz, jstring jstr) {
Invoking a tool method converts a string type in Java into a char* in the C language
char* CStr = _jstring2cstr (ENV,JSTR);
Call strlen to get the length of the CStr string
int length = strlen (CStr);
int i;
for (i = 0;i<length;i++) {
* (cstr+i) + = 1;
}
Return (*env)->newstringutf (ENV,CSTR);
}

Jniexport Jintarray Jnicall Java_com_itheima_javapassdata_jni_arrelementsincrease
(JNIENV * env, Jobject clazz, Jintarray Jarray) {
Jsize (*getarraylength) (jnienv*, Jarray);
Jsize length = (*env)->getarraylength (Env,jarray);
LOGD ("length =%d", length);
Jboolean iscopy;
jint* (*getintarrayelements) (jnienv*, Jintarray, jboolean*);
int* Arraypointer = (*env)->getintarrayelements (env,jarray,null);
int i;
for (i = 0;i<length;i++) {
* (arraypointer+i) + = 10;
}
return jarray;
}

output content to Logcat in C code
Android.mk文件增加以下内容LOCAL_LDLIBS += -llogC代码中增加以下内容#include <android/log.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__)
    • Define C macros define aliases #define LOGTag "System.out" to "System.out" Alias logTag
    • #define Logi (...) androidlogprint (android_logINFO, logTAG, _VAARGS)
    • Alias to androidlogprint function dead first two parameters priority second parameter tag
    • Fixed notation for variable parameters of VAARGS_
    • Logi (...) Use the same as printf () when calling.
C Code Callback Java Method (reflection)
    • ① Find Bytecode Object
      • Jclass (findclass) (jnienv, const char*);
      • The second parameter is the path to the class of the Java method where the callback is "Com/itheima/callbackjava/jni"
    • ② finding a method object from a byte-code object
      • Jmethodid (getmethodid) (jnienv, jclass, const char, const char);
      • The second parameter bytecode object The third parameter to reflect the calling Java method name fourth parameter to reflect the calling Java method signature
      • Get method Signature: Javap-s The full class name of the class to get the method signature/bin/classes run JAVAP
    • ③ creating Java objects by bytecode (optional) if the local method and the Java method to be recalled are in the same class, the created method can be invoked directly from the Java object passed by JNI.
      • Jobject obj = (*env)->allocobject (Env,claz);
      • When the callback method is not in the same class as the local method, you need to manually create a Java object from the byte-code object you just created.
      • The way to tune Java back through this object
      • It is important to note that if you are creating a callback method for an Activity object that also contains context this method does not work!!! return NULL pointer exception
    • ④ Reflection calls a Java method
      • void (Callvoidmethod) (jnienv, Jobject, Jmethodid, ...);
      • The second parameter calls the Java method's object the third parameter to call the Jmethodid object optional parameter that is received when the method is called

Example:

public class JNI {
static{
System.loadlibrary ("callback");
}
Private Context Mcontext;
Public JNI (Context context) {
Mcontext = context;
}
public native void Callbackvoidmethod ();

public native void Callbackintmethod ();

public native void Callbackstringmethod ();

public native void Callbackshowtoast ();
C Calling Java Null method
public void Hellofromjava () {
System.out.println ("Hello from Java");
}
C calling a method with two int parameters in Java
public int Add (int x,int y) {
return x+y;
}
C calling a method in Java with parameter string
public void printstring (String s) {
System.out.println (s);
}
public void Showtoast (String s) {
Toast.maketext (Mcontext, S, 0). Show ();
}
}

C File:

#include <jni.h>
#include <stdlib.h>
#include <android/log.h>
#define LOG_TAG "System.out"
#define LOGD (...) __android_log_print (Android_log_debug, Log_tag, __va_args__)
/**
* Convert a jstring to a C language char* type.
*/
char* _jstring2cstr (jnienv* env, jstring jstr) {
char* RTN = NULL;
Jclass clsstring = (*env)->findclass (env, "java/lang/string");
Jstring Strencode = (*env)->newstringutf (env, "GB2312");
Jmethodid mid = (*env)->getmethodid (env, clsstring, "GetBytes", "(ljava/lang/string;) [B");
Jbytearray Barr = (Jbytearray) (*env)->callobjectmethod (env, JSTR, Mid, Strencode); String. GetByte ("GB2312");
Jsize alen = (*env)->getarraylength (env, Barr);
jbyte* ba = (*env)->getbytearrayelements (env, Barr, Jni_false);
if (Alen > 0) {
RTN = (char*) malloc (alen+1); "The"
memcpy (RTN, BA, Alen);
rtn[alen]=0;
}
(*env)->releasebytearrayelements (env, Barr, ba,0);
return RTN;
}
jniexport void Jnicall Java_com_itheima_callbackjava_jni_callbackvoidmethod
(JNIENV * env, Jobject clazz) {
Jclass (*findclass) (jnienv*, const char*);
① Getting bytecode objects
Jclass Claz = (*env)->findclass (env, "Com/itheima/callbackjava/jni");
② Gets the method object, and the fourth parameter is the methods signature
Jmethodid (*getmethodid) (jnienv*, Jclass, const char*, const char*);
Jmethodid Methodid = (*env)->getmethodid (Env,claz, "Hellofromjava", "() V");
③ creating an object from a byte-code object
④ calling methods by object
void (*callvoidmethod) (jnienv*, Jobject, Jmethodid, ...);
(*env)->callvoidmethod (Env,clazz,methodid);

}

jniexport void Jnicall Java_com_itheima_callbackjava_jni_callbackintmethod
(JNIENV * env, Jobject clazz) {
① Getting bytecode objects
Jclass Claz = (*env)->findclass (env, "Com/itheima/callbackjava/jni");
② Get Method Object
Jmethodid Methodid = (*env)->getmethodid (Env,claz, "Add", "(II) I");
Jint (*callintmethod) (jnienv*, Jobject, Jmethodid, ...);
int result = (*env)->callintmethod (env,clazz,methodid,3,4);
LOGD ("result =%d", result);
}

jniexport void Jnicall Java_com_itheima_callbackjava_jni_callbackstringmethod
(JNIENV * env, Jobject clazz) {
① Getting bytecode objects
Jclass Claz = (*env)->findclass (env, "Com/itheima/callbackjava/jni");
② Get Method Object
Jmethodid Methodid = (*env)->getmethodid (Env,claz, "printstring", "(ljava/lang/string;) V");
//
jstring result = (*env)->newstringutf (env, "Hello from C");
(*env)->callvoidmethod (Env,clazz,methodid,result);
}
jniexport void Jnicall Java_com_itheima_callbackjava_jni_callbackshowtoast
(JNIENV * env, Jobject clazz) {
Jclass Claz = (*env)->findclass (env, "Com/itheima/callbackjava/jni");
Jmethodid Methodid = (*env)->getmethodid (Env,claz, "Showtoast", "(ljava/lang/string;) V");
Jobject (*allocobject) (jnienv*, Jclass);
Creating Java objects from bytecode objects here's the object that created the mainactivity.
Jobject obj = (*env)->allocobject (Env,claz);
jstring result = (*env)->newstringutf (env, "Hello from C");
void (*callvoidmethod) (jnienv*, Jobject, Jmethodid, ...);
(*env)->callvoidmethod (Env,clazz,methodid,result);
}

JNI Learning Note 2-java passed to the C-C code to logcat output content-C code callback Java method

Related Article

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.