AndroidStudio下JNI开发(easy+1.0)之自动编译

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,看图结果




可能遇到的问题

  1. 为什么我生成的C函数参数是(JNIEnv , jobject)而不是(JNIEnv , jclass); 
    答:这和java代码中对Native函数的声明有关,声明为static,这里的参数就是jclass,即代表该函数所在的类(如HelloJNI.getFromString(),这是jclass接收的是HelloJNI.class)。如果没有声明static,这里的参数就是jobject,表示调用者的实体对象,(如HelloJNI t=new HelloJNI();t.getFromCString(),这里jobject就代表就是t这个对象)。
  2. 报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 VersionGradle Version
0.1.02.5
0.2.02.5
0.3.0-alpha32.6
0.4.02.8
0.6.0-alpha12.8
0.6.0-alpha52.10
0.7.0-alpha12.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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值