Android Studio 2.2 JNI Demo

1 篇文章 0 订阅

1.设置NDK路径

    选择File -> Project structure,设置NDK路径,如果没有也可以在线下载。

2.新建project

    在创建引导界面中,选中support c/c++,此时Android studio会默认使用CMake工具,并在gradle 中进行相关的配置,创建完成后,主要配置的代码如下:

defaultConfig {
    applicationId "com.lc.jnitest"
    minSdkVersion 17
    targetSdkVersion 24
    versionCode 1
    versionName "1.0"
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    externalNativeBuild {
        cmake {
            cppFlags ""
        }
    }
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
externalNativeBuild {
    cmake {
        path "CMakeLists.txt"
    }
}


同时切换到Android 视图,最低部会有一个External Build Files,其中包含了一个CMakeList.txt,这个文件非常重要:

add_library( # Sets the name of the library.
         native-lib

         # Sets the library as a shared library.
         SHARED

         # Provides a relative path to your source file(s).
         # Associated headers in the same location as their source
         # file are automatically included.
         src/main/cpp/native-lib.cpp )

android studio 默认为创建一个JNI的示范程序,上面的“native-lib"指的是生成.so文件后的库名,"SHARED"是否作为一个分享库。
"src/main/cpp/native-lib.cpp"指的是所对应的c/c++文件,之前一般的.cpp或.c文件我们经常会创建一个文件夹”jni",这里android studio为我们创建好了cpp文件夹,专门放置c/c++文件。
在MainActivity中我们可以看到系统加载库以及java本地方法的声明:

public native String stringFromJNI();

// Used to load the 'native-lib' library on application startup.
static {
    System.loadLibrary("native-lib");
}
这里设置的库名必须与我们在CMakeList.txt中设置保持一致。

3.开始新建JNIDemo

这里我们首先在包名下创建一个叫util的包,在其中创建一个java类GetSum,代码片段如下:

public class GetSum {
public int number=10;
public ArrayList mArrayList;
public GetSum(){
    mArrayList = new ArrayList<>();
    mArrayList.add(5);
    mArrayList.add(7);
}
public  boolean isEqual(ArrayList<Integer> list){
    if(list.get(0) == list.get(1))
        return true;
    else
        return false;
}

static {
    System.loadLibrary("getSum");
}
public  native int sum(int a ,int b);
}

然后开始在cpp目录创建c++文件,源码如下:
#include<iostream>
using namespace std;
int getPart(int a, int b);
int getMin(int a, int b) {
    return a > b ? a : b;
}
extern "C"
jint
Java_com_lc_jnitest_util_GetSum_sum(
    JNIEnv *env,
    jobject /* this */ obj, jint a, jint b) {
    jclass getSum = env->GetObjectClass(obj);
    jfieldID numberId = env->GetFieldID(getSum, "number", "I");
    jint number = env->GetIntField(obj, numberId);
    jfieldID listId = env->GetFieldID(getSum, "mArrayList", "Ljava/util/ArrayList;");
    jobject list = env->GetObjectField(obj, listId);
    jmethodID jmethodID1 = env->GetMethodID(getSum, "isEqual", "(Ljava/util/ArrayList;)Z");
    jboolean equal = env->CallBooleanMethod(obj, jmethodID1, list);
    jclass listclass = env->GetObjectClass(list);
    jmethodID size_methodID = env->GetMethodID(listclass, "size", "()I");
    jint num = env->CallIntMethod(list, size_methodID);
    int temp = getPart(num, number);
    return a + b + number + num + temp + getMin(temp, num);
}
int getPart(int a, int b) {
    return a * b;
}`
这里有几点要注意:
1. "jint  Java_com_lc_jnitest_util_GetSum_sum(JNIEnv *env,jobject /* this */ obj, jint a, jint b)"该函数名称必须与你所声明的java方法进行对应。
    "jint"返回类型,对应上面的"int",函数名则是包名+类名+方法名,函数中的参数除了JNIENv *env,与jobject之外,另外的要与原先的方法保持一致。
    至于前两个参数如何使用,文章末尾会有相关的博客的链接方便进行学习。
2. 注意"extern "C""的位置,必须放在该对应函数的前面,否则运行会报错

接下来就需要修改CMakeList.txt的配置,本例配置如下:
target_link_libraries( getSum native-lib  ${log-lib} )`

修改完成后,进行rebuild project ,就可以运行。

本例参考链接:
代码编写:http://blog.csdn.net/jiangwei0910410003/article/details/17465457
工具配置:http://m.blog.csdn.net/article/details?id=51927631

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值