Android中如何动态引入so库


动态引入so库

为什么要动态引入so库?

遇到的问题:因为要做一些系统级别的工具,所以要调用一些系统的so库,如果把so库直接放在lib目录下的话,在android程序启动的时候会默认加载lib目录下的所有库,但是这些so库会在一些地方存在冲突,所以为了解决这个冲突的问题,就使用动态加载so库的方式,通过一些条件的判断是否要加载这个so库。

如何动态加载so库?

1.首先把so库放在assets资源目录下,一般会放两个so库,一个32位一个64位的
2.动态加载,就是在需要使用的时候,从assets资源目录下复制到app-libs目录下
public static boolean loadLibrary(Context context, String oldFileName, String libName) throws IOException {
        // 获取应用的私有模式的libs目录(真实的目录是app-libs)
        File libs_dir = context.getDir("libs", Context.MODE_PRIVATE);
	    // 可以获取到assets资源文件的数据流
        InputStream open = context.getAssets().open(oldFileName);
        String new_file_name = libs_dir.getPath() + "/" + libName;
		// 把资源文件的数据流写入到app-libs目录下
        if (!copyLibrary(open, new_file_name)) {
            return false;
        }
        try {
            System.load(new_file_name);
        } catch (Exception ex) {
            ex.printStackTrace();
            return false;
        }

        return true;
    }
//从assets资源目录下复制到app-libs目录下
    public static boolean copyLibrary(InputStream fileInputStream, String new_file) {

        FileOutputStream fos = null;
        try {

            File file = new File(new_file);
            fos = new FileOutputStream(file);
            int     dataSize;
            byte[]  dataBuffer = new byte[2048];

            while ((dataSize = fileInputStream.read(dataBuffer)) != -1) {
                fos.write(dataBuffer, 0, dataSize);
            }
            fos.flush();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            Log.e("NativeLibraryLoader",e.getMessage());
        } finally {
            try {
                if (fos != null) fos.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return false;
    }
3.判断系统是多少位的然后在静态代码块里加载不同的so库
static {
        //注册
        try {
            Context context = MainApplication.getContextObject();
            String osName = "lib32.so";
            //如果这个SUPPORTED_ABIS包含64就是64位的系统
            if (SUPPORTED_ABIS[0].contains("64")) {
                osName = "lib64.so";
            }
            NativeLibraryLoader.loadLibrary(context, osName, "libtv.so");
        } catch (Exception e) {
            e.printStackTrace();
        }
   }
4.存在问题

在没有关闭selinux的情况下,System.load(xxxx.so)会因为权限的原因导致失败 Permission denied;

如果权限够的话,可以直接使用暴力的方法,直接把assert目录的文件直接复制到lib目录下,然后使用System.loadLibrary(libsitatv.so)就能直接加载


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM