美文网首页
Android Studio 使用JNI笔记

Android Studio 使用JNI笔记

作者: YaAimo | 来源:发表于2016-07-18 05:15 被阅读0次

    主要记录一些as使用JNI的一些配置,避免忘记每次都要到处查找。。。
    使用as开发可以不用创建Android.mk文件,Application.mk文件,只要在build.gradle文件中配置相应的参数即可使用。。

    1.JNI文件的创建

    首先创建Java的native类

    
    public classMyJniTest {
    
    public native voidprint(String str);
    
    public native String getName();
    
    }
    
    

    然后运行项目,运行完成后在项目的build/intermediates/classes/debug/目录下面可以看到生成的MyJniTest.class文件,然后用java命令生成对应的JNI的.h文件,命令如下:

    
    bogon:asjnitest yjg$ cd build/intermediates/classes/debug/
    bogon:debug yjg$ ls
    android com
    bogon:debug yjg$ javah -jni com.jni.yjg.asjnitest.MyJniTest
    

    创建完成后就可以看到对应的.h文件,在../debug/下面

    B712C089-290A-4CFA-AD97-391F9A3F695C.png

    具体代码如下:

    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class com_jni_yjg_asjnitest_MyJniTest */
    
    #ifndef _Included_com_jni_yjg_asjnitest_MyJniTest
    #define _Included_com_jni_yjg_asjnitest_MyJniTest
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     com_jni_yjg_asjnitest_MyJniTest
     * Method:    print
     * Signature: (Ljava/lang/String;)V
     */
    JNIEXPORT void JNICALL Java_com_jni_yjg_asjnitest_MyJniTest_print
      (JNIEnv *, jobject, jstring);
    
    /*
     * Class:     getName
     * Signature: ()Ljava/lang/String;
     */
    JNIEXPORT jstring JNICALL Java_com_jni_yjg_asjnitest_MyJniTest_getName
      (JNIEnv *, jobject);
    
    #ifdef __cplusplus
    }
    #endif
    #endif
    

    2.JNI配置

    在项目的build.gradle文件中配置jni的参数了

    debug{   
           ndk{        
                moduleName "MyJniTest"//生成的so名字        
                stl "stlport_static"        
                ldLibs "log"   //实现__android_log_print    
                abiFilters "armeabi", "armeabi-v7a", "x86"  //输出指定三种  abi体系结构下的so库。    
          }
    }
    

    其中stl就相当于Android.mk文件中的APP_STL属性。大概就是导入C++运行时库吧。。
    abiFilters就相当.mk文件中的APP_ABI。用于生成不同架构的.so包。

    3.实现jni方法
    拷贝.h文件到项目的jni目录下面。(as的jni目录默认在main下面,需要自己创建,当然也可以在build.gradle中自己指定)
    创建对应的.cpp文件
    然后就是实现.h文件中的方法,.cpp文件的具体代码

    #include <jni.h>
    #include <com_jni_yjg_asjnitest_MyJniTest.h>
    #include <android/log.h>
    
    
    JNIEXPORT void JNICALL Java_com_jni_yjg_asjnitest_MyJniTest_print
    (JNIEnv * env, jobject obj, jstring jsstr){   
     __android_log_print(ANDROID_LOG_DEBUG,"android","hello  jni");
    }
    
     JNIEXPORT jstring JNICALL Java_com_jni_yjg_asjnitest_MyJniTest_getName
            (JNIEnv * env, jobject jobject1){
        return env->NewStringUTF("I'm jni");
    
    }
    

    ok以上就是JNI部分的实现了。
    然后就是java层调用jni了,先是加载jni库:

    static {   
     System.loadLibrary("MyJniTest");
    }
    

    接着就是调用jni的方法了:

    MyJniTest test=new MyJniTest();
    test.print("aaa");
    System.out.println("name:"+test.getName());
    

    OK 运行项目。。

    这个就是Logcal中打印出来日志:

    07-17 16:52:47.208 2211-2211/com.jni.yjg.asjnitest D/android: hello  jni
    07-17 16:52:47.208 2211-2211/com.jni.yjg.asjnitest I/System.out: name:I'm jni
    

    OK,这就说明java层通过JNI和C++交互成功了。
    补充说明:
    __android_log_print(ANDROID_LOG_DEBUG,"android","hello jni")这个是jni的log也能在Logcat中显示,可以用来调试C++代码,使用方法也和android的log类似,比如:ANDROID_LOG_DEBUG对应就是Log.d
    可以简单的封装下:

    #ifndef MY_APPLICATION_EBEN_HPC_LOG_H
    #define MY_APPLICATION_EBEN_HPC_LOG_H
    #ifdef __cplusplus
    extern "C" {
    #endif
    #include <android/log.h>
    // 宏定义类似java 层的定义,不同级别的Log LOGI, LOGD, LOGW, LOGE, LOGF。 对就Java中的 Log.i log.d
    #define LOG_TAG    "JNILOG" // 这个是自定义的LOG的标识
    //#undef LOG // 取消默认的LOG
    #define LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG, __VA_ARGS__)
    #define LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG, __VA_ARGS__)
    #define LOGW(...)  __android_log_print(ANDROID_LOG_WARN,LOG_TAG, __VA_ARGS__)
    #define LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG, __VA_ARGS__)
    #define LOGF(...)  __android_log_print(ANDROID_LOG_FATAL,LOG_TAG, __VA_ARGS__)
    
    #ifdef __cplusplus
    }
    #endif
    

    这样子使用的时候直接调用:

    LOGD("log.d 这是Jni中的log: xxxxxxx");
    

    这就和android中的log方法差不多了。。

    👌打完收工~~~~

    相关文章

      网友评论

          本文标题:Android Studio 使用JNI笔记

          本文链接:https://www.haomeiwen.com/subject/tespjttx.html