【JNI】拒绝各种坑!Android Studio 下创建JNI项目

   一时间来,又是几个月的时间没有写文章了,你干啥去了=。=,忙着各种事情,让我这几个月感触最深的,就是JNI了,JNI真是个有趣的东西,废话少说,咱们一起来看看,怎么用JNI来写一些有用的东西,因为网上的教程很多,很多。。真的很多,而且有些已经很老了或是不能那么弄,坑还是很多的,所以写了这篇文章,希望初学者能少走一点坑,需要注意的几点如下:

 

注意点:

1.本人也是JNI新手,所以不足之处请多交流指教;

2.本文采用的是Android Studio +NDK来实现JNI,如果使用的是Eclipse环境的话,这里推荐您去这个网址去学习Eclipse的JNI实现方法,保票肯定能用,地址:http://www.cnblogs.com/yejiurui/p/3476565.html

 


什么是NDK与JNI技术?

NDKNative Development Kit

The NDK is a toolset that allows you to implement parts of your app using native-code languages such as C and C++.(谷歌官方文档)

大致意思:NDK是一个工具,可以让你实现你的应用程序使用本地代码的语言,如C和C++的部分。

 

JNIJava Native Interface

它提供了若干的API实现了Java和其他语言的通信(主要是C&C++)。从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。

 

准备工作

Android Studio配置NDK

【转】http://www.android100.org/html/201509/18/182761.html

 

开始实现

 

1.用android studio创建新的项目

2.修改生成的文件

a.修改AppCompatActivity为Activity

 

 

2..主题样式为@android:style/Theme.Black.NoTitleBar并删除颜色属性,暂时还未尝试与Material Design结合,所以改下对JNI编译有影响的配置,后面我会尝试下是否支持

 

3.删除src下的test测试项目

 

3.修改Gradle

a.修改根目录下的build.gradle文件并同步

classpath 'com.android.tools.build:gradle:2.1.0'

 改为

classpath 'com.android.tools.build:gradle-experimental:0.7.0'

这个gradle是实验性的gradle和平时用的不太一样,修改后同步下,发现报错了,别担心,还没有修改完,刚刚修改完一个,报错图片如下:

 

 

b.修改app的gradle配置

因为配置很多我这里贴出代码:

原来的:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig {
        applicationId "com.windystory.hellojni"
        minSdkVersion 14
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.3.0'
}


修改后的配置:

 

/**
 * 这里不是 apply plugin: 'com.android.application' 了,很多原来的配置大部分都有 = 号了
 */
apply plugin: 'com.android.model.application'
/**
 * 这里不再是android开始了而是model
 */
model {
    android {
        compileSdkVersion 23
        buildToolsVersion "23.0.3"

        defaultConfig {
            applicationId "com.windystory.hellojni"
            minSdkVersion.apiLevel = 14  //最低版本的SDK设置
            targetSdkVersion.apiLevel = 23  //编译SDK设置
            versionCode =  1   //注意加 = 号
            versionName  = "1.0"
        }
        /*
         * 设置NDK编译moduleName
         */
        ndk {
            moduleName = 'hello-jni'
            toolchain = 'clang'
            CFlags.addAll(['-Wall'])
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles.add(file('proguard-rules.txt'))//这里不是原来的那个了
            }
        }

        productFlavors {
            create("arm") {
                ndk.abiFilters.add("armeabi")
            }
            create("arm7") {
                ndk.abiFilters.add("armeabi-v7a")
            }
            create("arm8") {
                ndk.abiFilters.add("arm64-v8a")
            }
            create("x86") {
                ndk.abiFilters.add("x86")
            }
            create("x86-64") {
                ndk.abiFilters.add("x86_64")
            }
            create("mips") {
                ndk.abiFilters.add("mips")
            }
            create("mips-64") {
                ndk.abiFilters.add("mips64")
            }
            // 包括所有的CPU架构
            create("all")
        }
    }
}

同步下,发现ok了

 

3.设置根目录下的gradle.properties支持NDK

android.useDeprecatedNdk=true

 


代码实现

 

1.创建JNI目录,右击src/main,创建JNI目录,并删除,app gradle的

android { sourceSets { main { jni.srcDirs = ['src/main/jni/','src/main/jni/'] } } } 

 删除后同步

 

2.创建一个名字叫JNI的类,并写一个native方法,native关键字修饰本地方法

 

public class JNI {
    public native String Hello();
}

在MainActivity中实例化该类

 

a.编译类 点击Build --- Make Project,完成后会在build-intermediates-classes-all-debug项目目录下生成相应的class文件,

使用Android studio的Terminal功能切到debug目录下(cd命令),然后使用 javah -jni 项目目录+类 来生成头文件,如图所示

 

使用javah -jni 命令生成头文件,注意如果出现未找到错误,请审查目录,注意不要进入到debug目录中,到debug目录即可,如果未出现错误,恭喜,成功了


 

b.将生成的头文件放入jni目录下,并实现该头文件

实现的.c中方法与头文件中一样,实现可以直接粘贴复制改下拓展名即可,注意实现类中需要将参数实现,并且引入头文件,在windows平台下NDK有一个bug,所以需要在jni目录下新建一个util.c的空文件

 

 

如出现如下编译问题,先关闭android studio手动删除build目录下的所有文件,打开后再次编译即可

 

需要注意的还有引用头文件时候,如果不是系统的头文件,一律使用" "来引用而不是<>,否则会报错

#include "com_windystory_hellojni_JNI.h"
/*
 * Class:     com_windystory_hellojni_JNI
 * Method:    Hello
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_windystory_hellojni_JNI_Hello
  (JNIEnv *evn, jobject obj)
{
   return (*evn)->NewStringUTF(evn, "Hello from My-JNI !");

}


c.使用本地方法

在MainActivity中调用JNI方法,需要将编译后的库引入,写在static静态块中,hello-jni这个名字要与gradle ndk配置中一样如下图所示:


 gradle ndk:

<span style="white-space:pre">	</span>/*
         * 设置NDK编译moduleName
         */
        ndk {
            moduleName = 'hello-jni'
            toolchain = 'clang'
            CFlags.addAll(['-Wall'])
        }

 好了,可以运行了,运行效果如下所示:


 

 

 Demo下载地址:

http://download.csdn.net/detail/u011539882/9523065

 

 

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值