Android Studio上编译JNI程序

1. 添加native接口

在需要使用Jni的类中添加native接口。

public class JniActivity extends Activity {
    private TextView tvJniTest = null;

    static{
        System.loadLibrary("JniTest");
    }

    public native String getStringFromNative();

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

        tvJniTest = (TextView) findViewById(R.id.tv_jni_test);
        tvJniTest.setText(getStringFromNative());
    }
}

2. 利用javah生成h头文件

点击Build–>Rebuild Project,生成.class文件。
编译OK后生成的class文件在AS工程的如下目录:

工程目录\moudle名\build\intermediates\classes\debug\

利用.class文件生成.h文件:
打开AS的命令控制台:View–>Tool Windows–>Terminal,进入工程class的目录,如:

cd exampletovey\build\intermediates\classes\debug

输入编译命令:

javah -d jni -classpath D:\eclipse_sdk\sdk\platforms\android-19\android.jar; com.genepoint.jni.JniActivity

回车后,会在debug\jni目录下生成对应的文件com_genepoint_jni_JniActivity.h,将该文件拷贝到模块的src\main\jni\目录下,整理改h文件如下:

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

#ifndef _Included_com_genepoint_jni_JniActivity
#define _Included_com_genepoint_jni_JniActivity
#ifdef __cplusplus
extern "C" {
#endif

/*
 * Class:     com_genepoint_jni_JniActivity
 * Method:    getStringFromNative
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_genepoint_jni_JniActivity_getStringFromNative
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

新建文件,com_genepoint_jni_JniActivity.c,实现如下:

#include "com_genepoint_jni_JniActivity.h"

/*
 * Class:     com_genepoint_jni_JniActivity
 * Method:    getStringFromNative
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_genepoint_jni_JniActivity_getStringFromNative
  (JNIEnv *env, jobject jObj){
    return (*env)->NewStringUTF(env,"Hello From JNI!");
}

执行Build–>Make Project,会报错误:

NDK not configured.

提示未配置NDK,需要在工程的local.properties文件中配置NDK路径。

3. 配置NDK

在项目的local.properties文件中,加入如下配置:

sdk.dir=D:\eclipse_sdk\sdk
ndk.dir=D:\eclipse_sdk\ndk

并在gradle.properties中加入如下语句:

android.useDeprecatedNdk=true

在当前Module中的build.gradle中的defaultConfig分支中加入如下语句:

ndk {
	moduleName "JniTest"		// so文件的名字
	abiFilters "armeabi","armeabi-v7a","x86"  // 需要编译的平台
}

在Windows下NDK存在一个bug,当仅仅编译一个文件时出现会出现此问题,解决方法就是再往jni文件夹加入一个空util.c文件即可。

4. 进行编译so文件

执行Build–>Rebuild Project,就可以编译出so文件。
生成的so文件在build/intermediates/ndk/lib/目录下。
运行该模块,即可在app中加载并调用该so文件了,生成的apk直接将so打包好了,不需要进行第5步。

5. 在AS项目中,调用so文件

. 首先,将so文件拷贝到模块的libs目录下
. 编写模块的build.gradle文件,在android块下,增加如下内容(与 defaultConfig同一级):

    task nativeLibsToJar(type: Zip, description: "create a jar archive of the native libs") {  
        destinationDir file("$projectDir/libs")  
        baseName "Native_Libs2"  
        extension "jar"  
        from fileTree(dir: "libs", include: "**/*.so")  
        into "lib"  
    }  
  
    tasks.withType(JavaCompile) {  
        compileTask -> compileTask.dependsOn(nativeLibsToJar)  
    }  

. 直接运行该模块,即可直接运行生成apk
. 第5步直接使用so文件的方法与之前的编译so方法不能共存

遇到的部分问题及解决方法

.1、 c及.h文件中,显示Cannot find jni.h文件,导致代码中与JNI C有关的关键字全部为红色。
参考资料:http://stackoverflow.com/questions/21096819/jni-and-gradle-in-android-studio
解决方法:在程序的build.gradle中,android{defaultConfig{***}}defaultConfig中添加如下代码:

sourceSets.main{
			jni.srcDirs = []
			jniLIbs.srcDir 'src/main/libs'
		}

但是添加该代码后,会在.c和.h文件上部一直提示Sync Now,同步后也没有效果,一直没有去掉,重启也不能去掉。
解决方法:删除.externalNativeBuild和build文件夹后重新编译即可。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值