NDK development some tricky issues

javah

Whenever we create a native method, the corresponding C layer method name should be Java_package name class name method name. It's easy to make mistakes every time you have to write it yourself. Here we can use the javah command to help us achieve this.

1. Open the dos command line, or the Terminal module that comes with as
2. Jump to the top level of the package name, generally we go to the project /app/src/main/java folder
3. Call javah -jni package name .classname

javap

This command can help us obtain the signature of the method. Generally, a unique method can be identified according to the method name and method signature.

1 Find the class file of the class whose signature method needs to be obtained. All class files in the as directory are stored in the app/build/intermediates/classes/debug folder. Find the corresponding class file.

cd app/build/intermediates/classes/debug/…

2. Call the command
javap -s com.xxx.MainActivity

Android.mk

In general, to compile c files, we can use the gcc tool, but if we want to compile all c files in batches, we need to do it through the configuration file makefile script. The makefile script configuration specification of the c file in jni can be viewed through ANDROID-MK.html in the docs folder , but the AS downloaded folder does not include the docs folder. The main configuration content is posted here.

   ---------- cut here ------------------
   LOCAL_PATH := $(call my-dir)

   include $(CLEAR_VARS)

   LOCAL_MODULE    := hello-jni
   LOCAL_SRC_FILES := hello-jni.c

   include $(BUILD_SHARED_LIBRARY)
   ---------- cut here ------------------

Application.mk

This file also exists in the JNI folder, which can configure the generated so library corresponding to the cpu, and generate all types of so libraries by default. The configuration is as follows:

APP_ABI
    By default, the NDK build system will generate machine code for the
    'armeabi' ABI. This corresponds to an ARMv5TE based CPU with software
    floating point operations. You can use APP_ABI to select a different
    ABI.

    For example, to support hardware FPU instructions on ARMv7 based devices,
    use:

        APP_ABI := armeabi-v7a

    Or to support both ARMv5TE and ARMv7 based devices, use:

        APP_ABI := armeabi armeabi-v7a

The type generally has armeabi armeabi-v7a x86

Some configuration of C code

sleep

The c code developed under win has a sleep(int) function to help the code achieve sleep. However, this function cannot be used in the unix system, and the import package needs to be implemented:

#include <unistd.h>

strcmp

This function implements the comparison of two c strings, which cannot be used directly in some systems. It can be implemented by using the import package:

#include <string.h>

Returns 0 if the 2 strings are equal.

java string to c string

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); //"\0"
        memcpy(rtn, ba, alen);
        rtn[alen]=0;
    }
    (*env)->ReleaseByteArrayElements(env, barr, ba,0);
    return rtn;
}

c string to java string

(*env)->NewStringUTF(env,text)

c code to call java method

The way it operates is somewhat similar to reflection, the code is as follows:

//jclass      (*FindClass)(JNIEnv*, const char*);
    jclass clazz=(*env)->FindClass(env,"com/a520it/alipayndksample/MainActivity");
    //jmethodID GetMethodID(jclass clazz, const char* name, const char* sig)
    jmethodID methodId=(*env)->GetMethodID(env,clazz,"dismissDialog","()V");
    //void        (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
    (*env)->CallVoidMethod(env,obj,methodId);

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325958863&siteId=291194637