Android JNI开发示例

Posted ZhangJianIsAStark

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android JNI开发示例相关的知识,希望对你有一定的参考价值。

看源码和写项目时,见过很多JNI和Native相关的代码。
有一定C/C++功底的前提下,在既有的框架上,
修改和增加JNI、Native代码其实并不是一件困难的事。

不过自己一直没有记录开发JNI的完整步骤,即搭建出框架的方法。
本篇博客就从一个简单的例子入手,看看开发JNI的过程。


1
首先,我们在module中新建一个文件,用于加载JNI库并定义Native方法。
对应的代码类似于:

package work.test;

/**
 * @author zhangjian on 18-3-16.
 */

public class JniMethod 
    //最后编译出的JNI库名称为libJniMethod.so
    static 
        System.loadLibrary("JniMethod");
    

    //定义了Native方法名称
    public static native int getDoubleRet(int input);

2
接着我们利用javac命令生成JniMethod对应的.class文件:

然后,回退到Java文件对应的根目录,利用javah生成.class文件对应的native头文件:

生成的native头文件内容类似于:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class work_test_JniMethod */

#ifndef _Included_work_test_JniMethod
#define _Included_work_test_JniMethod
#ifdef __cplusplus
extern "C" 
#endif
/*
 * Class:     work_test_JniMethod
 * Method:    getDoubleRet
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_work_test_JniMethod_getDoubleRet
  (JNIEnv *, jclass, jint);

#ifdef __cplusplus

#endif
#endif

当然不利用javac和javah,仅按照native函数的命名规则,
我们也可以直接写出native头文件。
不过有工具还是方便的多。

3
现在我们可以在module中新建一个jni目录,并将native头文件放入其中。
头文件名可以任意修改,此处我们将其修改为JniMethod.h。

然后在jni目录下创建同名的c文件实现头文件,类似于:

#include <jni.h>

jint Java_work_test_JniMethod_getDoubleRet (JNIEnv* env,
        jclass inputClass, jint inputInt) 
    return 2 * inputInt;

4
接着我们在jni目录下,创建编译jni库需要的android.mk和Application.mk文件。
Android.mk的内容类似于:

# Copyright (C) 2009 The Android Open Source Project
# ............
# 其实就是指定目录、文件名及最终生成的模块名
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := JniMethod
LOCAL_SRC_FILES := JniMethod.c
include $(BUILD_SHARED_LIBRARY)

Application.mk的内容类似于:

# 此处可以指定具体的abi
APP_ABI := all

5
现在进入Android.mk所在目录,即jni目录进行ndk-build即可。

将生成的so文件移动到module的libs目录下。

6
最后在是使用时,在module的build.gradle中增加一下语句即可:

    sourceSets 
        main 
            jniLibs.srcDir 'libs'
            jni.srcDirs = []
        
    

实际使用的代码类似于:

/**
 * @author zhangjian
 */
public class MainActivity extends AppCompatActivity 
    private int mCounter = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = findViewById(R.id.test);
        button.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View view) 
                //直接调用
                int ret = JniMethod.getDoubleRet(mCounter);
                Log.d("Test", "Ret: " + ret);
                ++mCounter;
            
        );
    

至此,我们应该大致了解JNI开发的基本方法。
剩下的就是在各个步骤,按照具体的需求进行修改和完善了。

以上是关于Android JNI开发示例的主要内容,如果未能解决你的问题,请参考以下文章

Android开发实践:Java层与Jni层的数组传递

Android Studio 的 Hello-JNI [关闭]

Android 使用 jni Demo示例

Android 使用 jni Demo示例

Android Studio 如何使用jni

FFmpeg 示例代码,用于从静止图像 JNI Android 创建视频文件