http://www.open-open.com/lib/view/open1451917048573.html
Java Native Interface (JNI)标准是java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI 是本地编程接口,它使得在 Java 虚拟机 (VM) 内部运行的 Java 代码能够与用其它编程语言(如 C、C++ 和汇编语言)编写的应用程序和库进行交互操作。
由于Android的应用层的类都是以Java写的,这些Java类编译为Dex型式的Bytecode之后,必须靠Dalvik虚拟机(VM: Virtual Machine)来执行。VM在Android平台里,扮演很重要的角色。
(多的咱不说了,介绍什么的 到处都有可以去搜一下)
咱们先建一个NdkJniDemo的工程
新建工程.png
新建JniUtils类实现native方法
public class JniUtils { public static native String getStringFormC(); }
build.png
然后clean project 再rebuild project 生成class文件,
这时候打开如下图的文件夹看是否生成了classes文件夹,没有生成请重新来过。
文件夹.png
再打开Terminal输入指令cd app/build/intermediates/classes/debug
然后再输入指令javah -jni com.wobiancao.ndkjnidemo.ndk.JniUtils
注意 这里javah -jni后面跟的是JniUtils类的全路径,如果javah报不存在之类的,是你的java环境没有配置好。
Paste_Image.png
这时候打开classes/debug下面的文件发现多了一个文件com_wobiancao_ndkjnidemo_ndk_JniUtils.h
然后在src/main下新建文件夹jni,把生成的.h文件复制或者剪切到jni文件夹下面去,新建一个c类随便取一个名字,添加代码如下
//// Created by XY on 16/1/4.//#include "com_wobiancao_ndkjnidemo_ndk_JniUtils.h"/* * Class: Java_com_wobiancao_ndkjnidemo_ndk_JniUtils * Method: getStringFormC * Signature: ()Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_com_wobiancao_ndkjnidemo_ndk_JniUtils_getStringFormC (JNIEnv *env, jobject obj){ return (*env)->NewStringUTF(env,"这里是来自c的string");
这里发现头文件#include <jni.h>
报红色,是因为咱们还没有配置ndk环境,打开file->project structure
选择你所下载的ndk环境路径,如果没有ndk这里有个地址大家可以去下载 一个安卓工具集合的网站:http://androiddevtools.cn/
Paste_Image.png
设置好了之后,发现头文件还是红色的,然后再build一下工程,就会有提示
Error: NDK integration is deprecated in the current plugin. Consider trying the new experimental plugin. For details, see http://tools.android.com/tech-docs/new-build-system/gradle-experimental. Set "android.useDeprecatedNdk=true" in gradle.properties to continue using the current NDK integration.
按着提示做就行了 在gradle.properties文件末尾添加android.useDeprecatedNdk=true
就ok啦
然后在app文件下得build.gradle ->defaultConfig括号内添加如下代码
ndk { moduleName "NdkJniDemo" //生成的so名字 abiFilters "armeabi", "armeabi-v7a", "x86" //输出指定三种abi体系结构下的so库,目前可有可无。}
到了这一步重新build项目,发现已经没有变红了。接下来就是运用了,在JniUtils类里面添加如下代码
static { System.loadLibrary("NdkJniDemo");//之前在build.gradle里面设置的so名字,必须一致}
然后简单调用就行了,MainActivity代码如下
public class MainActivity extends AppCompatActivity { TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = (TextView) findViewById(R.id.ndk_text); textView.setText(JniUtils.getStringFormC()); } }
运行结果如图
运行图.png
咱们打开app->intermediates-ndk-debug发现生成了三个文件夹,并且对应了之前我们在build.gradle配置的abiFilters
大功告成。
新建libs文件夹把这三个文件夹放进去
Paste_Image.png
然后删除咱们的jni文件试试,是否工程还能运用?
ok 教程完毕
最后出一个利用jni的Aes加密demo运行结果如图所示
Aes加密.png
项目地址:https://github.com/a12a15a05/NdkJniDemo
谢谢star欢迎点赞=。=转载请注明来源
来自: http://www.jianshu.com/p/d8cde65cb4f7
Android Studio进行NDK开发笔记
http://blog.csdn.net/enlangs/article/details/51881718
方案一
- AS自带的有NDK插件,但是会出现Deprecated错误。解决方法:按提示操作即可。
-
AS的NDK插件不需要编写Application.mk和Android.mk,所以自己编写的无效!!,关键是那插件功能太弱了(很多Android.mk的属性不能修改)。如果想用自己的mk文件,需要在app/build.gradle中打掉NDK的所有配置。
android { compileSdkVersion 23 buildToolsVersion "23.0.2" defaultConfig { applicationId "ckm.xxx.testndk" minSdkVersion 19 targetSdkVersion 23 versionCode 1 versionName "1.0" // 如果要使用自己的Application.mk和Android.mk需要修改下面2处。 // 修改1,直接打掉下面配置 // ndk{ // moduleName "test" // abiFilters "armeabi","armeabi-v7a" // } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } // sourceSets { main { jni.srcDirs = ['src/main/jni'] } } // 修改2,需要把jni.srcDirs设置为空。 // sourceSets { // main { // jni.srcDirs = [] // } // } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
-
自动生成头文件,在extend tool中增加配置:
参数内容:
Program:C:Program FilesJavajdk1.8.0_25injavah.exe
Parameters:-v -jni -d $ModuleFileDir$srcmainjni $FileClass$
Working directory:$SourcepathEntry$
- 1
- 2
- 3
- 1
- 2
- 3
设置结果
- 设置ndk-build的extend tool
Program:C:
dk
dk-build.cmd
Parameters:NDK_PROJECT_PATH=$ModuleFileDir$/build/intermediates/ndk NDK_LIBS_OUT=$ModuleFileDir$/src/main/jniLibs NDK_APPLICATION_MK=$ModuleFileDir$/src/main/jni/Application.mk APP_BUILD_SCRIPT=$ModuleFileDir$/src/main/jni/Android.mk V=1
Working directory:$SourcepathEntry$
- 1
- 2
- 3
- 1
- 2
- 3
最终结果:
疑惑:
- 我不相信AS不支持mk文件(只能当做文本文件识别),肯定有地方设置,还为找到设置地方。
注意:
如果按照上面的方式使用自定义Android.mk那么AS将无法识别到native函数。
方案二
来源:http://stackoverflow.com/questions/21096819/jni-and-gradle-in-android-studio
此方案主要是直接修改build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 14
buildToolsVersion "20.0.0"
defaultConfig {
applicationId "com.example.application"
minSdkVersion 14
targetSdkVersion 14
ndk {
moduleName "YourModuleName"
}
}
sourceSets.main {
jni.srcDirs = [] // This prevents the auto generation of Android.mk
jniLibs.srcDir 'src/main/libs' // This is not necessary unless you have precompiled libraries in your project.
}
task buildNative(type: Exec, description: 'Compile JNI source via NDK') {
def ndkDir = android.ndkDirectory
commandLine "$ndkDir/ndk-build",
'-C', file('src/main/jni').absolutePath, // Change src/main/jni the relative path to your jni source
'-j', Runtime.runtime.availableProcessors(),
'all',
'NDK_DEBUG=1'
}
task cleanNative(type: Exec, description: 'Clean JNI object files') {
def ndkDir = android.ndkDirectory
commandLine "$ndkDir/ndk-build",
'-C', file('src/main/jni').absolutePath, // Change src/main/jni the relative path to your jni source
'clean'
}
clean.dependsOn 'cleanNative'
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn buildNative
}
}
dependencies {
compile 'com.android.support:support-v4:20.0.0'
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
参考:图片和extend tool设置都来自这位博主,非常感谢。
参考(请同事写了段代码处理下):
#!/bin/sh
for arg in "$@"
do
if [[ $arg == NDK_PROJECT_PATH=* ]];then
param1=`echo $arg | awk -F = '{printf $1}'`
elif [[ $arg == APP_BUILD_SCRIPT=* ]];then
param2=`echo $arg | awk -F = '{printf $2}'`
else
param="$param $arg"
fi
done
#echo $param2
param2=`echo $param2 | sed 's#build/intermediates/ndk/debug/Android.mk#src/main#g'`
#echo $param2
#echo ""
if [[ -n "$param1" ]] && [[ -n "$param2" ]]
then
param1="$param1=$param2"
param="$param1 $param"
fi
DIR="$(cd "$(dirname "$0")" && pwd)"
$DIR/build/ndk-build $param