zoukankan      html  css  js  c++  java
  • 动态加载sd卡或者手机内置存储卡的so库

    package com.wsc.utils;
    
    import android.content.Context;
    
    import com.wsc.common.Entrance;
    import com.wsc.common.SDKCommon;
    
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    
    /**
     * so库从sd卡拷贝到app的私有目录下,并进行比对验证和加载<p></p>
     * Created by win10-JYcainiao on 2018/1/24.
     */
    
    public class LoadSoFileUtils {
        private static final String TAG = LoadSoFileUtils.class.getSimpleName();
    
        /**
         * 加载 so 文件
         *
         * @param context
         * @param soPath  下载到得sdcard目录
         */
        public static void loadSoFile(Context context, String soPath, LoadSoFileListener loadSoFileListener) throws Exception {
            if (Entrance.loacSo) {
                KLog.d(TAG, "so已经加载过了");
                return;
            }
            //存放so文件的私有目录
            File appLibs = context.getApplicationContext().getDir("libs", Context.MODE_PRIVATE);
            //需要加载的so文件
            File soDir = new File(soPath);
            File[] soFiles = null;
            //获取so来源文件夹下的所有so文件
            if (soDir.exists() && soDir.isDirectory()) {
                soFiles = soDir.listFiles();
            }
            //看看需要加载的so文件
            if (!soFileExisted(appLibs, soFiles) && soFiles != null) {
                copy(soPath, appLibs.getAbsolutePath());
            }
            //获取app私有目录下的文件列表
            File[] currentFiles = appLibs.listFiles();
            if (!loadSoFileListener.compareSo(currentFiles)) {
                KLog.d(TAG, "so验证未通过");
                loadSoFileListener.onError();
                return;
            }
            //记录加载的so个数
            int loacSoFileCount = 0;
            //根据so文件名称加载so文件
            for (int i = 0; i < currentFiles.length; i++) {
                for (int j = 0; j < SDKCommon.soFileNames.length; j++) {
                    if (currentFiles[i].getName().contains(SDKCommon.soFileNames[j])) {
                        try {
                            System.load(currentFiles[i].getAbsolutePath());
                            loacSoFileCount++;
                        } catch (Exception e) {
                            throw new Exception("加载so库失败,soName = " + currentFiles[i].getName());
                        }
                    }
                }
            }
            //判断需要加载的so是否加载完全
            if (loacSoFileCount == SDKCommon.soFileNames.length) {
                Entrance.loacSo = true;
                loadSoFileListener.onSuccess();
            } else {
                loadSoFileListener.onError();
            }
        }
    
        /**
         * 判断 so 文件是否存在
         *
         * @param soFolder 需要存放so库的app私有文件夹
         * @param soFiles  需要动态加载的so文件
         * @return 需要加载的so文件是否存在
         */
        private static boolean soFileExisted(File soFolder, File... soFiles) {
            int count = 0;
            if (soFolder.exists()) {
                File[] files = soFolder.listFiles();
                if (files != null && files.length > 0) {
                    for (int i = 0; i < files.length; i++) {
                        for (int j = 0; j < soFiles.length; j++) {
                            if (files[i].getName().equals(soFiles[j].getName()) && files[i].length() == soFiles[j].length()) {
                                count++;
                            }
                        }
                    }
                }
            }
            if (count == 6) {
                return true;
            }
            return false;
        }
    
        /**
         * @param fromFile 指定的下载目录
         * @param toFile   应用的包路径
         * @return
         */
        private static int copy(String fromFile, String toFile) {
            //要复制的文件目录
            File[] currentFiles;
            File root = new File(fromFile);
            //如同判断SD卡是否存在或者文件是否存在,如果不存在则 return出去
            if (!root.exists()) {
                return -1;
            }
            //如果存在则获取当前目录下的全部文件 填充数组
            currentFiles = root.listFiles();
            //目标目录
            File targetDir = new File(toFile);
            //创建目录
            if (!targetDir.exists()) {
                targetDir.mkdirs();
            }
            //遍历要复制该目录下的全部文件
            for (int i = 0; i < currentFiles.length; i++) {
                if (currentFiles[i].isDirectory()) {
                    //如果当前项为子目录 进行递归
                    copy(currentFiles[i].getPath() + "/", toFile + currentFiles[i].getName() + "/");
                } else {
                    //如果当前项为文件则进行文件拷贝
                    if (currentFiles[i].getName().contains(".so")) {
                        int id = copySdcardFile(currentFiles[i].getPath(), toFile + File.separator + currentFiles[i].getName());
                        KLog.d(TAG, currentFiles[i].getName());
                    }
                }
            }
            return 0;
        }
    
        //文件拷贝
        //要复制的目录下的所有非子目录(文件夹)文件拷贝
        private 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;
            }
        }
    
        public interface LoadSoFileListener {
            void onSuccess();
    
            void onError();
    
            /**
             * 验证so
             *
             * @param loadSofile 需要验证的so
             */
            boolean compareSo(File... loadSofile);
        }
    }
    

      

  • 相关阅读:
    Diagnostic Viewer 显示空白
    ROS 的一些常用命令行功能
    ROS学习(更新中~)
    ubuntu坑(持续更新~)
    PHP延迟静态绑定:static关键字
    php实战正则表达式:验证手机号
    mysql 查询日志
    索引对更新语句速度影响很大
    给table设置滚动条
    PHP 对字符串进行十六进制替换 invalid character in attribute value
  • 原文地址:https://www.cnblogs.com/fengchuxiaodai/p/8352686.html
Copyright © 2011-2022 走看看