美文网首页Android技术知识Android开发Android开发
Android Studio快速实现一个JNI示例

Android Studio快速实现一个JNI示例

作者: kevinsong0810 | 来源:发表于2018-12-03 19:40 被阅读1次

    前提:Android Studio 3.0,预先通过SDK Manager安装好CMake(生成so库的编译相关工具),3.6.4版

    1. 定义一个Java类,其中定义native方法,并调用System.loadLibrary加载so库
    public class TestJni {
        static {
            System.loadLibrary("test-jni");
        }
        public static native String getStringFromNativeMethod();
    }
    

    测试调用的例子:

    public class MainActivity extends Activity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            // call native method, LogUtils是封装的Log类
            LogUtils.d("print: " + TestJni.getStringFromNativeMethod());
        }
    }
    
    1. 通过javah指令生成C/C++头文件.h
      sudo javah -jni com.kevin.test.TestJni
      生成的头文件名称:com_kevin_test_TestJni.h,内容如下:
    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class com_kevin_test_TestJni */
    
    #ifndef _Included_com_kevin_test_TestJni
    #define _Included_com_kevin_test_TestJni
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     com_kevin_test_TestJni
     * Method:    getStringFromNativeMethod
     * Signature: ()Ljava/lang/String;
     */
    JNIEXPORT jstring JNICALL Java_com_kevin_test_TestJni_getStringFromNativeMethod
      (JNIEnv *, jclass);
    
    #ifdef __cplusplus
    }
    #endif
    #endif
    

    注意,javah前:
    a. 需要先make project一次,生成TestJni.class文件
    b. 先cd至命令执行的路径:app/build/intermediates/classes/debug,否则会找不到TestJni.class

    1. 复制头文件至源代码路径下面,例如:app/src/main/jni,并新建一个cpp文件,名字:com_kevin_test_TestJni.cpp,完成函数getStringFromNativeMethod的C++定义,如下:
    #include "com_kevin_test_TestJni.h"
    
    JNIEXPORT jstring JNICALL Java_com_kevin_test_TestJni_getStringFromNativeMethod
      (JNIEnv *env, jclass thiz) {
          return (*env).NewStringUTF("this is c++ code");
      }
    

    注意:
    这里C/C++都可以,C的source文件结尾为.c,C++的source文件结尾为.cpp,但是语法实现时不能有错,否则编译时会报错。这里选用C++

    1. Java代码,C++代码都准备完成后,这时要准备编译C++的CMakeList.txt,新建即可。作用是CMake工具的配置文件,必不可少。简单配置如下:
    cmake_minimum_required(VERSION 3.4.1)
    
    add_library( # Specifies the name of the library.
                 test-jni
                 # Sets the library as a shared library.
                 SHARED
                 # Provides a relative path to your source file(s).
                 com_kevin_test_TestJni.cpp )
    

    注意:这里定义了编译生成的库文件名字,test-jni,编译完成后,文件名称为:libtest-jni.so。

    1. 更新app下build.gradle文件,添加Cmake相关信息
    android {
        ...
        defaultConfig {
            ...
            externalNativeBuild {
                cmake {
                    abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a' // 定义编译的ABI类型,每种会编译生成一个对应的so库文件
                }
            }
        }
        ...
        externalNativeBuild {
            cmake {
                path 'src/main/jni/CMakeLists.txt'
            }
        }
    }
    
    1. 重新编译新的Project,并安装至手机,运行。此时打印的日志:
      12-03 18:47:03.636 9016 9016 D kevintest: print: this is c++ code
      说明Activity运行时,调用native方法getStringFromNativeMethod成功,方法实现在libtest-jni.so库中。另外,可以通过Build->Anaylze APK,查看apk中,lib路径下已打包4个libtest-jni.so库,分别存放至arm64-v8a等文件夹下,提供不同的ABI支持

    最后,附上示例Project结构的截图:




    参考文档:https://developer.android.com/studio/projects/add-native-code#create-cmake-script


    作者:kevin song,2018.12.3于南京建邺区

    相关文章

      网友评论

        本文标题:Android Studio快速实现一个JNI示例

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