android studio怎么调用jni
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android studio怎么调用jni相关的知识,希望对你有一定的参考价值。
参考技术A (1)老版本,方法如下:task copyNativeLibs(type: Copy) from(new File(project(':MyProject').buildDir, 'native-libs')) include '**/*.so' into new File(buildDir, 'native-libs') tasks.withType(Compile) compileTask -> compileTask.dependsOn copyNativeLibs clean.dependsOn 'cleanCopyNativeLibs' tasks.withType(com.android.build.gradle.PackageApplicationTask) pkgTask -> pkgTask.jniDir new File(buildDir, 'native-libs')(2)新版本三种方法:(2.1)打包前先生成.Jar文件后自动解包到apk文件task nativeLibsToJar(type: Zip, description: 'create a jar archive of the native libs') destinationDir file("$buildDir/native-libs") baseName 'native-libs' extension 'jar' from fileTree(dir: 'libs', include: '**/*.so') into 'lib/' tasks.withType(Compile) compileTask -> compileTask.dependsOn(nativeLibsToJar)下面一句话就是打包生成目录(build\native-libs)中的.jar文件compile fileTree(dir: "$buildDir/native-libs", include: 'native-libs.jar')(2.2)手动生成.Jar文件后自动解包到apk文件这个方式需要自己手动进行.SO文件压缩,具体步骤为:将所有需要使用的.so文件压缩为.zip文件(zip中的文件目录结构为: lib/armeabi/*.so)然后把zip文件后缀改为.Jar然后放到libs生成apk就ok默认就是自动打包所有.Jar文件:dependencies compile fileTree(dir: 'libs', include: '*.jar')(2.3)这也就是现在正在使用的方式(推荐) ,其实无非就是把.SO文件打包到APK的lib文件夹中,假如仔细阅读了Gradle的使用方法,自然就知道其实Gradle官方在新版已经自动实现了打包.SO文件的.很简单级就是在配置的android节点下加入下面的内容就ok:sourceSets main jniLibs.srcDirs = ['libs'] 其他地方无需修改,整个项目的配置文件如下:apply plugin: 'android' android compileSdkVersion 19 buildToolsVersion "19.0.0" defaultConfig minSdkVersion 16 targetSdkVersion 19 versionCode 1 versionName "1.0" buildTypes release runProguard false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' sourceSets main jniLibs.srcDirs = ['libs'] dependencies compile fileTree(dir: 'libs', include: ['*.jar'])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技术?
NDK:Native 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++的部分。
JNI:Java 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
以上是关于android studio怎么调用jni的主要内容,如果未能解决你的问题,请参考以下文章