Android 动态加载sd卡里面so库

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_16064871/article/details/82859110

有些so文件太大,可以从手机内存或者sd卡里面拷贝到运行的应用程序里面。接口都是之前打包在里面了。还可以做so更新,就是把之前拷贝进行删除,然后进行不重新打包apk,进行重新拷贝进去。

1,封装好的类

package com.rtcmdemo.until;

import android.content.Context;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

/**
 * so库从sd卡拷贝到app的私有目录下,并进行比对验证和加载
 */

public class LoadSoFileUtils {
    private static String nameSO = "libSaveLib";

    /**
     * 加载 so 文件
     */
    public static int loadSoFile(Context context, String fromPath) {
        File dir = context.getDir("jniLibs", Context.MODE_PRIVATE);
        String fromPathFile = fromPath + "/" + nameSO + ".so";
        File isExist = new File(fromPathFile);
        if (!isLoadSoFile(dir, isExist.exists())) {
            return copy(fromPath, dir.getAbsolutePath());
        } else {
            return 0;
        }
    }

    /**
     * 判断 so 文件是否存在
     */
    public static boolean isLoadSoFile(File dir, Boolean isExist) {
        File[] currentFiles;
        currentFiles = dir.listFiles();
        boolean hasSoLib = false;
        if (currentFiles == null) {
            return false;
        }
        for (File currentFile : currentFiles) {
            //判断里面是否存在这个库,以及sd也有这个库,那就删除,然后进行外面拷贝进去
            if (currentFile.getName().contains(nameSO)) {
                hasSoLib = isExist && !currentFile.delete();
            }
        }
        return hasSoLib;
    }

    public static int copy(String fromFile, String toFile) {
        //要复制的文件目录
        File[] currentFiles;
        File root = new File(fromFile);
        //如同判断SD卡是否存在或者文件是否存在,如果不存在则 return出去
        if (!root.exists()) {
            return -1;
        }
        //如果存在则获取当前目录下的全部文件 填充数组
        currentFiles = root.listFiles();

        if (currentFiles == null) {
            return -1;
        }
        //目标目录
        File targetDir = new File(toFile);
        //创建目录
        if (!targetDir.exists()) {
            targetDir.mkdirs();
        }

        int statue = -1;
        //遍历要复制该目录下的全部文件
        for (File currentFile : currentFiles) {
            if (currentFile.isDirectory()) {
                //如果当前项为子目录 进行递归
                copy(currentFile.getPath() + "/", toFile + currentFile.getName() + "/");
            } else {
                //如果当前项为文件则进行文件拷贝
                if (currentFile.getName().contains(".so")) {
                    statue = copySdcardFile(currentFile.getPath(), toFile + File.separator + currentFile.getName());
                }
            }
        }
        return statue;
    }


    //文件拷贝
    //要复制的目录下的所有非子目录(文件夹)文件拷贝
    public static int copySdcardFile(String fromFile, String toFile) {
        try {
            FileInputStream fosfrom = new FileInputStream(fromFile);
            FileOutputStream fosto = new FileOutputStream(toFile);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = -1;
            while ((len = fosfrom.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
            }
            // 从内存到写入到具体文件
            fosto.write(baos.toByteArray());
            // 关闭文件流
            baos.close();
            fosto.close();
            fosfrom.close();
            return 0;
        } catch (Exception ex) {
            return -1;
        }
    }
}

2,使用方式

        File dir = this.getDir("jniLibs", Activity.MODE_PRIVATE);
        String ext = FilePathManage.GetInstance().getDataDirectory();

        try {
            LoadSoFileUtils.loadSoFile(this, ext);
            File[] currentFiles;
            currentFiles = dir.listFiles();
            for (File currentFile : currentFiles) {
                System.load(currentFile.getAbsolutePath());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

注意外部加载都是使用:               

System.load(currentFile.getAbsolutePath());  里面参数就是so全路径

注意jar接口里面不要带有下面,因为会跟上面冲突。因为我们有时习惯自已编译库里面直接写了下面这个。

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

记得自已加上权限

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

猜你喜欢

转载自blog.csdn.net/qq_16064871/article/details/82859110