NDK开发的简单入门

使用Android studio3.0开发的,不需要创建对应的native方法的.h文件。定义完了native方法后,就可以在cpp文件中使用就可以了。

1.自定义log打印

#include <android/log.h>
#define TAG "NDKProject"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG , TAG , __VA_ARGS__);
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO , TAG , __VA_ARGS__);
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN , TAG , __VA_ARGS__);
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR , TAG , __VA_ARGS__);
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL , TAG , __VA_ARGS__);

2.创建一个类,里面加载对应的cpp库和定义相应的成员。

public class Native {
    companion object {
        init {
            System.loadLibrary("native-lib")
        }
    }

    /**
     * A native method that is implemented by the 'native-lib' n
     * which is packaged with this application.
     */
    external fun stringFromJNI(): String

    /**
     * 在native层读写文件
     */
    external fun upDateFile(file_path: String): Void

    external fun upDateString(): String

    external fun upDataIntArray(array: IntArray): IntArray

    //定义被jni调用的native方法
    external fun JNICallJava():Void

    //普通方法供jni调用
    public fun loadMessage(data: String){
        printMessage(data)
    }
    private fun printMessage(data: String){
//        println(data);
        Log.i("TAG" , data);
    }   
}

3.对应的cpp文件内容:

#include <jni.h>
#include <string>
#include <android/log.h>
#define TAG "NDKProject"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG , TAG , __VA_ARGS__);
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO , TAG , __VA_ARGS__);
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN , TAG , __VA_ARGS__);
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR , TAG , __VA_ARGS__);
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL , TAG , __VA_ARGS__);

using namespace std;

extern "C" JNIEXPORT jstring

JNICALL
Java_com_myself_ndkproject_Native_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {    
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

extern "C" JNIEXPORT void

JNICALL
Java_com_myself_ndkproject_Native_upDateFile(JNIEnv *env, jclass jclass, jstring path) {
    const char *file_path = env->GetStringUTFChars(path, NULL);
    if (file_path == NULL) {
        return;
    }
    FILE *file = fopen(file_path, "a+");
    if (file == NULL) {
        return;
    }
    char data[] = "I'm a body";
    int count = fwrite(data, strlen(data), 1, file);
    fclose(file);
    env->ReleaseStringUTFChars(path, file_path);
}


extern "C" JNIEXPORT jstring
JNICALL
Java_com_myself_ndkproject_Native_upDateString(JNIEnv *env , jboolean jclass ){
    std::string upDate = "upDateString from c";
    return env->NewStringUTF(upDate.c_str());
}

/**操作数组的两种方式:
 * 1.生成native层的数组拷贝。
 * 2.调用数组指针进行操作。
 */
extern "C" JNIEXPORT jintArray
JNICALL
Java_com_myself_ndkproject_Native_upDataIntArray(JNIEnv *env , jclass jclass , jintArray jarray){
    /*jint jniArray[5];
    jint leng = env->GetArrayLength(jarray);
    env->GetIntArrayRegion(jarray , 0 , leng , jniArray);

    for (int i = 0; i < leng; ++i) {
        jniArray[i] += 5;
        LOGI("I = %d" , jniArray[i]);
    }
    env->SetIntArrayRegion(jarray , 0 , leng , jniArray);*/

    //得到数组的指针
    jint* data = env->GetIntArrayElements(jarray , NULL);
    //得到数组的长度
    jsize leng = env->GetArrayLength(jarray);
    for (int i = 0; i < leng; ++i) {
        data[i] += 3;
        LOGI("*I = %d" , data[i]);
    }

    //释放数组资源和数组指针
    env->ReleaseIntArrayElements(jarray , data , 0);
    return jarray;
}

extern "C" JNIEXPORT void
JNICALL
Java_com_myself_ndkproject_Native_JNICallJava(JNIEnv *env , jclass jclass1){
    //获取类
    jclass cls_native = env->FindClass("com/myself/ndkproject/Native");
    if (cls_native == NULL){
        return;
    }
    //获取loadMessage静态方法:第三个参数是方法的ID
    jmethodID methodID = env->GetMethodID(cls_native , "loadMessage" , "(Ljava/lang/String;)V");
    if (methodID == NULL){
        return;
    }

    //找到对应的构造方法
    jmethodID structure = env->GetMethodID(cls_native , "<init>" , "()V");
    if (structure == NULL){
        return;
    }

    //得到类的实例
    jobject native_class = env->NewObject(cls_native , structure , NULL);
    if (native_class == NULL){
        return;
    }

    //调用相对用的普通方法
    jstring str = env->NewStringUTF("call instance method");
    env->CallVoidMethod(static_cast<_jclass *>(native_class), methodID , str);

    env->DeleteGlobalRef(cls_native);
    env->DeleteGlobalRef(reinterpret_cast<jobject>(methodID));
    env->DeleteGlobalRef(reinterpret_cast<jobject>(structure));
    env->DeleteGlobalRef(native_class);
    env->DeleteGlobalRef(str);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值