AndroidStudio2.2.3 JNI与NDK开发之二:生成可调用jar包

本文是继前文 

AndroidStudio2.2.3 JNI与NDK开发之一:生成可调用.so库的跟进文章

       主要用于解决生成的.so库中,jni的方法名有包名的限制,导致其他项目工程引用时,包名不一致,出现jni层接口调用无效的问题。即,A项目的a.so,在B项目使用时,报uncaughtException的错误,导致程序崩溃。

uncaughtException Ljava/lang/ThreadGroup;
12-30 23:07:09.936 4604-4604/com.example.jnitest E/AndroidRuntime: FATAL EXCEPTION: main
                                                                   Process: com.example.jnitest, PID: 4604
                                                                   java.lang.UnsatisfiedLinkError: getJniString
                                                                       at com.example.jnitest.JniUtil.getJniString(Native Method)
                                                                       at com.example.jnitest.MainActivity.onCreate(MainActivity.java:15)
                                                                       at android.app.Activity.performCreate(Activity.java:5451)
                                                                       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)

引起这个崩溃的原因是,jni的getJniString接口对应的包名为com.example.jnidemo,而本项目中包名为com.example.jnitest.

       一般来说,编译的.so库就是为了使用方便,通用性好,不管本项目工程或者是其他的项目工程,于是要编译出一个适用性强的.so提供使用,需要将jni层的.so对应Java层的类接口打包成一个.jar,给其他项目工程使用,其他工程使用时,只需要添加.jar包和.so文件即可。本文主要介绍新建一个Library,生成.so和jar提供给其他工程使用。


1、新建项目为JniTest

(1)、为JniTest新建Module,选择Android Library命名为jnilibrary


然后再java的com.example.jnilibrary下新建JniUtil.java,如图:


JniUtil的内容依然为测试内容

public class JniUtil {

    static {
        System.loadLibrary("JniUtil");
    }

    public static native String getJniString();

    public static native int getJniAdd(int a, int b);

}
接下来就是进行jni操作,编译.so库的步骤,也是在src\main文件下新建jni文件夹,如图:


配置build.gradle和Project Structure中ndk-build路径,具体步骤参考前一篇文章

(2)、配置并生成jar文件

主要是对JniUtil.java生成.jar文件。

在jnilibrary这个module下的build.gradle中配置如下信息

def SDK_NAME = "JniUtil";
def SDK_VERSION = "_V1.0";
def sdkDestinationPath = "build";
def zipFile = file('build/intermediates/bundles/release/classes.jar')

task deleteBuild(type: Delete) {
    delete sdkDestinationPath + SDK_NAME + SDK_VERSION + ".jar"
}

task makeJar(type: Jar) {
    from zipTree(zipFile)
    from fileTree(dir: 'src/main',includes: ['assets/**'])
    baseName = SDK_NAME + SDK_VERSION
    destinationDir = file(sdkDestinationPath)
}

makeJar.dependsOn(deleteBuild, build)
声明jar的文件名,版本,路径,以及编译依赖的编译文件等。完整的build.gradle文件如下:

apply plugin: 'com.android.library'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"

    defaultConfig {
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    sourceSets {
        main {
            jni.srcDirs = ['src/main/jni', 'src/main/jni/']
        }
    }

    externalNativeBuild {
        ndkBuild {
            path file("src\\main\\jni\\Android.mk")
        }
    }


}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.1.0'
    testCompile 'junit:junit:4.12'
}

def SDK_NAME = "JniUtil";
def SDK_VERSION = "_V1.0";
def sdkDestinationPath = "build";
def zipFile = file('build/intermediates/bundles/release/classes.jar')

task deleteBuild(type: Delete) {
    delete sdkDestinationPath + SDK_NAME + SDK_VERSION + ".jar"
}

task makeJar(type: Jar) {
    from zipTree(zipFile)
    from fileTree(dir: 'src/main',includes: ['assets/**'])
    baseName = SDK_NAME + SDK_VERSION
    destinationDir = file(sdkDestinationPath)
}

makeJar.dependsOn(deleteBuild, build)

接下来下Android Srudio的Gradle窗口,找到makejar(没有时,Gradle窗口左上角的刷新按钮进行刷新),双击。如图:




等待编译一会在如下目录下生成想要的.jar文件:


3、新建一个Test项目工程验证,目录结构如下图


在真机上运行如下结果



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值