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开发的基本方法。
剩下的就是在各个步骤,按照具体的需求进行修改和完善了。

猜你喜欢

转载自blog.csdn.net/gaugamela/article/details/79581562
今日推荐