Android 加载SDCard中so库

本文介绍了在Android项目中,由于第三方要求将so库放在SDCard上,而Android系统默认不允许直接加载SDCard中的so库。为解决此问题,文章提出了将so库拷贝到应用私有libs目录再进行加载的方案。详细步骤包括从SDCard拷贝so库到应用私有目录,并展示了相关工具类方法。虽然不推荐这种方式,但作为应对特殊情况的解决方案进行了分享。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目背景

最近项目与第三方合作,对方提供so接口,我们进行实现,要求我们将so库放在sdcard中。
我们知道sdcard中的so没有执行权限,那么直接通过dlopen打开sdcard中so的方式并不可取。不得已,在网上找的一种解决方法:将sdcard中的so库拷贝到应用的私有libs库,然后再使用dlopen方式进行打开。
当然dlopen是在c/c++里面进行调用的,如果我们需要java层面进行调用的话,可以使用System.load方法。

实现

1.拷贝sdcard so至 应用私有libs中

工具类方法如下:

public class NativeLibraryLoader {

    public static boolean loadLibrary(Context context, String libPath, String libName) {
		// 获取应用的私有模式的libs目录。
        File libs_dir = context.getDir("libs", Context.MODE_PRIVATE);
        Log.e("NativeLibraryLoader", libs_dir.getAbsolutePath());
        String new_file_name = libs_dir.getPath() + "/" + libName;
        String old_file_name = libPath + "/" + libName;
        if (!copyLibrary(new_file_name, old_file_name)) {
            Log.e("NativeLibraryLoader", "copy Library failed");
            return false;
        }

        try {
            System.load(new_file_name);
        } catch (Exception ex) {
            ex.printStackTrace();
            return false;
        }

        return true;
    }

	//项目中会拷贝sdcard中的so库至私有目录
    public static boolean copyLibrary(String new_file_name, String old_file_name) {

        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            File new_file = new File(new_file_name);
            File old_file = new File(old_file_name);

            /* delete old library if exists. */
            if (new_file.exists()) new_file.delete();

            fis = new FileInputStream(old_file);
            fos = new FileOutputStream(new_file);

            int     dataSize;
            byte[]  dataBuffer = new byte[2048];

            while ((dataSize = fis.read(dataBuffer)) != -1) {
                fos.write(dataBuffer, 0, dataSize);
            }
            fos.flush();

            return true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (fos != null) fos.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                if (fis != null) fis.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return false;
    }
}

在测试过程中,为了查看我们私有模式的libs路径,进行了打印,其中xxx.xxx.xxx为应用包名。
使用了几部手机,都是如下路径。

E/NativeLibraryLoader: /data/user/0/xxx.xxx.xxx/app_libs

2.加载so库

NativeLibraryLoader.loadLibrary(this, "/mnt/sdcard", "libnative-lib.so");

总结

其实这种使用方式并不被推荐,仅考虑一种情况:so库放在sdcard中如果被用户误删的情况下如何处理。
因为是第三方要求如此处理,我也没有办法。只好如此了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值