使用aar库封装c++动态库并在Android app中使用

  我们要使用某服务的SDK,但是对方只有纯c++风格的第三方的arm架构的动态库(.so),因此无法直接在java app中直接使用,需要将原始so库封装成符合JNI命名规范的so库(以下简称JNI so库),然后才能通过JNI在java app中使用。我的需求并非直接在Android app中使用JNI so库,而是再把JNI so库封装一层,封装成Android app能直接使用的jar包或aar包,其实就是做成Android SDK发布。所以实质是将c++的SDK封装为Android SDK。

  1. 环境搭建
    安装jdk
    安装Android studio
    下载SDK、NDK
    (添加环境变量)

  2. 新建AS项目和AAR Moudle
    a. File -> New -> New Project, 选择add no activity,命名为 JNITest
    b. local.properties中添加ndk路径,如ndk.dir=D:\android-ndk-r16-beta1
    c. gradle.properties中添加 android.useDeprecatedNdk=true
    d. File -> New -> New Moudle -> Android Library 命名为ALibrary

  3. 在AAR Moudel中生成JNI so库和aar包
    a. 在ALibrary的build.gradle的android.defaultConfig中添加

    ndk {
        moduleName "clib"
        stl "stlport_static"
        ldLibs "log", "z", "m"
        abiFilters "armeabi-v7a", "x86"
    }

    b. 创建native接口JNIInterface.java

    package com.lp.alibrary;
    /**
     * Created by 10256 on 2017/9/27.
     */
    public class JNIInterface {
        static {
            System.loadLibrary("clib"); // 与ALibrary.build.gradle.android.defaultConfig.ndk.moduleName的值一致
        }
        public native String name();
    }

    然后build项目生成class文件。

    c. 通过javah命令生成符合JNI规范的c++头文件
    打开cmd,cd到ALibrary所在目录,然后运行

    E:\ShareFolder\project\AndroidStudioProjects\JNITest\alibrary>javah -classpath build\intermediates\classes\debug -jni -d src\main\jni com.lp.alibrary.JNIInterface

    比如我项目是在E:\ShareFolder\project\AndroidStudioProjects\JNITest,注意-classpath后面跟的不是.class文件路径,只要写类package所在路径就行,不要在后面添加\com\lp\alibrary,-d告诉.h文件放到哪,最后的目标要写类全路径名。
    项目文件tree
    然后在src\main\jni下生成了符合JNI规范的.h文件。

    d. 在jni下新建c++源文件实现接口

    
    #include "com_lp_alibrary_JNIInterface.h"
    
    
    #include <Android/log.h>
    
    
    
    #define TAG "MainActivity"
    
    
    #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG ,__VA_ARGS__)
    
    
    /*
     * Class:     com_lp_alibrary_JNIInterface
     * Method:    name
     * Signature: ()Ljava/lang/String;
     */
    JNIEXPORT jstring JNICALL Java_com_lp_alibrary_JNIInterface_name
      (JNIEnv *env, jobject jobj) {
        LOGI("Java_com_lp_alibrary_JNIInterface_name");
        return env->NewStringUTF("Hello From JNI!");
    }

    后面我会在这里调用第三方so库。然后rebuild,在build/intermediates/ndk/debug/lib下生成JNI so库,在build/output/aar下生成aar包。

  4. 在Android app中使用aar包
    然后可以把这个aar包当成普通的jar文件给别的模块用了。

    a. 打开任意一个Android app,File -> New Module -> Import .JAR/.AAR Package 然后FileName浏览到刚才生成的.aar文件
    b. File -> Project Structure -> Moudle.app -> Dependencies -> add -> Moudle Dependence -> alibrary-debug
    c. 在MainActivity中使用AAR包中的native接口

    public class MainActivity extends AppCompatActivity {
    
        public static final String TAG = "MainActivity";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            Log.i(TAG, new JNIInterface().name());
        }
    }

    然后make && run,控制台里输出

    09-27 19:41:07.915 22781-22781/com.lp.vehicle I/MainActivity: Java_com_lp_alibrary_JNIInterface_name
    09-27 19:41:07.915 22781-22781/com.lp.vehicle I/MainActivity: Hello From JNI!

    大功告成。

有些人可能还在用eclipse开发Android,所以他不认aar包,只认jar包,那么在 alibrary.build.gradle中添加

task makeJar(type: Copy) {
    delete 'build/libs/alib.jar'
    from('build/intermediates/bundles/release/')
    into('build/libs/')
    include('classes.jar')
    rename('classes.jar', 'alib.jar')
}
makeJar.dependsOn(build)

然后打开右侧的Gradle窗口 -> 选中 :alibrary -> Execute gradle task -> Command line 中输入 makeJar ,然后点ok,然后看到alibrary\build\libs下生成了alib.jar。
gradle task
在其他项目使用该模块时,将jar包复制到app\libs下,同时要把build/intermediates/bundles/release/jni下的JNI so库复制到app\src\main\jniLibs下,jniLibs不存在则新建。这样就能通过jar包的方式使用该模块了。
file tree

参考:
android studio 实现类似百度地图 发布SDK机制实现(jni实现调用C++的so库,并封装jar包)
android 解决studio生成aar包并在其他工程引用aar包的坑,不需要任何gradle配置
ndroid tips(八)–>Android Studio打包apk,aar,jar包
AndroidStudio如何引入so包

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值