1.module下的build.gradle
apply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion 19
buildToolsVersion "19.1.0"
defaultConfig {
applicationId "cinread.jj.jniexample"
minSdkVersion.apiLevel = 16
targetSdkVersion.apiLevel 19
versionCode 1
versionName "1.0"
}
ndk {
moduleName "mobi_jj"
ldLibs.addAll(['android','log'])
abiFilters.addAll(['armeabi', 'armeabi-v7a', 'x86'])
}
buildTypes {
release {
minifyEnabled false
proguardFiles.add(file('proguard-rules.txt'))
}
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:19.1.0'
}
2. app 下的 build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.0-beta1'
classpath 'com.android.tools.build:gradle-experimental:0.8.0-beta1' //不行就用0.7+
//classpath 'com.android.tools.build:gradle:2.14.1'
//classpath 'com.android.tools.build:gradle-experimental:0.7+'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
3. 打开AndroidStudio- Settings - Tools - ExternalTools
新增一个Tool
programe: c:\Program Files\Java\jdk1.8.0_65\bin\javah.exe
Parameters: -d ..\jni $FileClass$
directory: $ModuleFileDir$\src\main\java\
4.在JniTest 你要的类中 写好你需要的同名本地方法,利用as的自动提示 新建好c文件
5.以后右键包含 静态加载so 的 niTest类 点击javah即可生成h文件到jni下
6.在JniTest下
package cinread.jj.jniexample;
/**
* Created by pengjf on 2016/8/18.
*/
public class JniTest {
static{
System.loadLibrary("mobi_jj");
}
public native String stringFromJNI();
public native String stringFromJNItwo();
}
光标移动到native方法上面,利用快捷键alt+enter自动在jni文件夹下创建了mobi_jj.c代码
gradle/wrapper/gradle-wrapper.properties
#Fri Aug 19 11:35:38 CST 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
7.gradle.properties
android.useDeprecatedNdk=true
改吧改吧就好了
附上 mobi_jj.c
#include "cinread_jj_jniexample_JniTest.h"
#define JNI_FN(A) Java_cinread_jj_jniexample_JniTest_ ## A
#include <android/log.h>
#define LOG_TAG "libmupdf"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
JNIEXPORT jstring JNICALL
JNI_FN(stringFromJNI)(JNIEnv *env, jobject instance) {
// TODO
LOGI("first log");
return (*env)->NewStringUTF(env, "string A from JNI");
}
JNIEXPORT jstring JNICALL
JNI_FN(stringFromJNItwo)(JNIEnv *env, jobject instance) {
// TODO
LOGI("second log");
return (*env)->NewStringUTF(env, "string B from JNI");
}
改了首句 由 #include < jni.h> 改成了 生成的头文件
#include "cinread_jj_jniexample_JniTest.h"
7.最后一步 点击工具栏上的Build - Make 生成so,看图结果
可能遇到的问题
- 为什么我生成的C函数参数是(JNIEnv , jobject)而不是(JNIEnv , jclass);
答:这和java代码中对Native函数的声明有关,声明为static,这里的参数就是jclass,即代表该函数所在的类(如HelloJNI.getFromString(),这是jclass接收的是HelloJNI.class)。如果没有声明static,这里的参数就是jobject,表示调用者的实体对象,(如HelloJNI t=new HelloJNI();t.getFromCString(),这里jobject就代表就是t这个对象)。 - 报java.lang.UnsatisfiedLinkError错误;
答:此类错误一般后面有详细的解释,此处列出常见的错误:
- could’t find “xxx.so” 此类错误表示找不到对应的so文件,请查看自己的gradle配置是否有ndk标签,函数实现文件要用标准的后缀.cpp或.c,不然gradle编译ndk的时候不会加入编译的。
- Native method not found 此类问题表明你在JAVA中声明的函数没有对应的Native实现,如果已经实现了,请确保执行了System.loadLibary(“xxx.so”);一般来说用javah生成的函数定义是不会出现签名不一致的情况的。
- Can’t load 64-bit .so on 32-bit platform 也就是说不能在32位环境中载入64位的so。一般来说把so移到armeabi-v8a 文件夹下即可。该文件夹存放的是arm64位so文件。
注意事项:
使用Experimental插件进行NDK开发
使用Experimental插件的必要条件
1、Gradle-2.5或更高版本
2、Android Studio 1.3 RC1或更高版本
3、Android NDK r10e 或更高版本
4、Build Tools 19.0.0 或更高版本
每个版本的experimental插件需要特定的Gradle版本
Plugin Version | Gradle Version |
---|---|
0.1.0 | 2.5 |
0.2.0 | 2.5 |
0.3.0-alpha3 | 2.6 |
0.4.0 | 2.8 |
0.6.0-alpha1 | 2.8 |
0.6.0-alpha5 | 2.10 |
0.7.0-alpha1 | 2.10 |
参考文献
http://tools.android.com/tech-docs/new-build-system/gradle-experimental 民间大神guide
https://github.com/googlesamples/android-ndk/tree/master/hello-libs google官方sample