Android studio 创建一个JNI工程

环境:
  • Android studio 2.1.2
  • android-ndk-r10e
创建一个jni工程:
  • 首先新建一个Android项目,刚刚建好的项目目录结构如下所示:
    这里写图片描述

  • 然后设置NDK路径,在local.properties文件中加入一行ndk.dir=你自己ndk所在路径

  • 新建的项目默认是不包含jni的,因此我们要手动增加一个jni目录
    这里写图片描述
    如图,我们在app目录下面创建一个jni目录,这个jni目录存放C、C++代码和mk文件。因为在NDK编译的时候,会去jni目录下面找mk文件,根据mk文件执行编译。
    在创建jni目录的时候我们选择改变默认的路径,让jni目录在app目录之下。
    这里写图片描述
    创建好jni目录之后,在jni目录添加mk文件,包括Android.mk和Application.mk,编译脚本基本都是在Android.mk文件里面,Application.mk里面可以设置一些编译选项,比如ABI,STL库设置等等。
    接下来我们就可以编写代码了。

  • 找到MainActivity类文件(在app/src/main/java目录下),在MainActivity类里面添加jni接口

public native String getStringFromJni();

注意:jni接口需要用native关键字声明
java中接口定义好之后,我们要在底层实现。也就是用C或者C++实现我们在MainActivity类里面定义的getStringFromJni方法。

  • 在app/jni目录下增加hello.cpp文件,在里面写getStringFromJni方法的实现
#include <jni.h>

extern "C"
{

    jstring Java_com_example_www_hellojni_MainActivity_getStringFromJni(JNIEnv* jni, jobject obj)
    {
        return jni->NewStringUTF("Hello jni!");
    }

}//extern "C"

这里写图片描述

如图方法名称要遵循一定的规则,从左到右依次是Java_包名_类名_方法名,包名里面的“.”换成 “_” 按照这样的方式去命名,通过这样的规则,jni方法被调用的时候才可以找得到它具体的实现。

因为是C++代码,所以要加extern “C”,将C++代码按照C代码去编译。

  • 然后我们需要编写mk脚本,打开Android.mk文件,在里面写入如下脚本:
LOCAL_PATH := $(call my-dir)        #设置LOCAL_PATH为本文件所在路径

include $(CLEAR_VARS)               #初始化LOC_ 变量

LOCAL_MODULE    := hello-jni        #设置so名称,该设置下将会编译产生libhello-jni.so文件,前面的lib和后面的.so是编译之后自动添加的

LOCAL_SRC_FILES := hello.cpp        #需要编译的源文件,如果源文件不在app/jni目录下,需要加上路径

include $(BUILD_SHARED_LIBRARY)     #执行动态库编译,如果是BUILD_SHARED_LIBRARY,就会编译静态库

以上脚本就会把hello.cpp编译为一个libhello-jni.so文件

  • 接着编写Application.mk,一般我们可以设置ABI,如下:
APP_ABI := all                      #所有平台都编译
APP_ABI := armeabi-v7a mips x86     #只编译armeabi-v7a、mips、x86这三个平台
  • 紧接着我们还要设置build.gradle,在app/build.gradle文件里写入下面代码:
android{
...
    sourceSets {
        main {
                jniLibs.srcDir('libs')//生成的so文件在这个目录里面app/libs
        }
    }
}
task NDKBuildDebug(type: Exec) {
    Properties properties = new Properties()
    properties.load(project.rootProject.file('local.properties').newDataInputStream())
    def ndkDir = properties.getProperty('ndk.dir') + '/ndk-build.cmd'
    commandLine ndkDir, 'V=0', '-j10', 'NDK_DEBUG=1', 'NDK_LOG=1'
}

project.afterEvaluate {
    compileDebugNdk.dependsOn 'NDKBuildDebug'
}
  • 最后我们要先载入动态库,然后再调用jni接口,MainActivity里面代码如下:
public class MainActivity extends AppCompatActivity {

    static {
        //Android.mk文件里面指定的模块名称 “LOCAL_MODULE := hello-jni”
        System.loadLibrary("hello-jni");    
    }

    public native String getStringFromJni();

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        TextView  tv = new TextView(this);
        tv.setText( getStringFromJni() );
        setContentView(tv);
    }
}

最后编译,运行。
这里写图片描述

这样一个简单的jni工程就建好了,希望对刚开始接触的朋友有所帮助。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值