Android将so库封装到jar包中并加载其中的so库

之前写过将jar包和so库封装到jar包中的文章,但是没有考虑别人调用时需要加载so库的问题。因为so库放入jar之后,so就不是一个独立的.so文件了,用System.load()加载就会提示找不到这个库,所以要想加载这个so 就需要把so 从jar 中提取出来,保存为临时文件,然后再加载。但是不能直接提取.so文件,需要把.so文件改成.jet文件封装到jar中,再进行提取拷贝。

如何建立一个项目以及项目的结构还有模块我就不说,可以看我之前的文章:Android 将module中的jar、so包打包成jar或者aar文件
我这里只是对so库封装到jar包做一些修改,这样方便后续项目加载so库。

1.将so后缀改成.jet,然后放到下图目录中,如果有多个cpu架构可以放多个。再新建SysLoad.java类,这个类可以不用写代码。

2.修改build.gradle文件task makeJar(type: Jar)方法

apply plugin: 'com.android.library'android {    compileSdkVersion 29    defaultConfig {        minSdkVersion 22        targetSdkVersion 29        versionCode 1        versionName "1.0"        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"    }    sourceSets {        main {//            jni.srcDirs = []//                jniLibs.srcDirs = ['src/main/jniLibs']//设置目标的so存放路径        }    }    buildTypes {        release {            minifyEnabled false            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'        }        lintOptions {            abortOnError false        }    }    task makeJar(type: Jar){        //删除存在的        delete 'build/libs/newsdk.jar'  //删除存在的        archivesBaseName = 'newsdk'  //输出的jar包名称        from(project.zipTree('build/intermediates/packaged-classes/release/classes.jar'))        from(project.zipTree('build/intermediates/packaged-classes/release/libs/AMap_Search_V7.1.0_20191030.jar')) //需要打包的第三方jar包//        from fileTree(dir: "src/main/java", include: "**/*.so") //把src/main/java目录下包含的所有.so文件封装到jar包        from fileTree(dir: "src/main/java", include: "**/*.jet") //把src/main/java目录下包含的所有.jet文件封装到jar包        destinationDir = file('build/libs')  //打成jar包后存放的文件目录    }    makeJar.dependsOn(build)}dependencies {    testImplementation 'junit:junit:4.12'    implementation files('libs/AMap_Search_V7.1.0_20191030.jar')}

3.点击makejar编译出jar包,将其引入到项目中,打开可以看到里面包含了a.jet和b.jet文件,如下图。

4.在项目中通过Java代码加载jar中的so库,这里只展示加载a.so库。原理:获取a.jet的文件流,再把文件流输入到临时文件a.so中, System.load()方法加载a.so文件(简单点说,就是把a.jet文件拷贝出来),这样就可以了。

static {    try {        InputStream is = null;        is =  SysLoad.class.getResourceAsStream("/com/example/libraryb/arm64-v8a/a.jet");        File tempFile = File.createTempFile("a", ".so");        FileOutputStream fos = new FileOutputStream(tempFile);        int i;        byte[] buf = new byte[1024];        while ((i = is.read(buf)) != -1) {            fos.write(buf, 0, i);        }        is.close();        fos.close();        System.load(tempFile.getAbsolutePath());    } catch (IOException e) {        e.printStackTrace();    }}

注意:提取a.jet文件时,要注意改一下/com/example/libraryb/arm64-v8a/a.jet路径,改成你自己的。

更多相关文章

  1. Android(安卓)性能优化之Loading Big Bitmaps
  2. android和ios,音频互通方案
  3. android音乐播放器-------使用android系统自带的数据库
  4. 工程中导入sqlite -sqlite 基础教程(1)
  5. 解决 Android(安卓)Studio 创建项目时极其的慢的尴尬
  6. 资深Android研发全面总结:Flutter遇到的那些坑
  7. Android(安卓)64bit系统中app以32bit运行
  8. android 显示gif图片实例详解
  9. android的 网络下载和数据持久化

随机推荐

  1. Android(安卓)监听软键盘弹起和收起事件
  2. 系出名门Android(10) - HTTP 通信, XML
  3. Android(安卓)ContentProvider的使用
  4. Android之ScrollLayout左右滑动效果实现
  5. android:layout_gravity="bottom"不起作
  6. android AsyncTask学习
  7. Android(安卓)List divider显示不出来的
  8. android 格式化
  9. Android(安卓)屏幕横竖切换详解
  10. android 按键