Android 用DexClassLoader加载插件APK中的工具类

本文中插件APK工具类包名:cn.kang.plugin.PluginUtil

工具类中的方法也很简单,两个int类型的数相加


MainActivity代码:

public class MainActivity extends AppCompatActivity {

    private String cacheDir;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        cacheDir = getCacheDir().getPath();

        try {
            // 将 插件APK 保存在本地路径
            LoadUtils.copyAssetAndWrite(this, "plugin-debug.apk");

            // 创建 插件APK 的 类加载器
            DexClassLoader dexClassLoader = new DexClassLoader(cacheDir + "/plugin-debug.apk",
                    getDir("dex", 0).getAbsolutePath(), null, getClassLoader());

            // 用 类加载器 加载 插件APK中的类
            Class<?> pluginClass = dexClassLoader.loadClass("cn.kang.plugin.PluginUtil");
            Method method = pluginClass.getDeclaredMethod("pluginMethodAdd", int.class, int.class);
            Object result = method.invoke(null, 3, 4);
            Log.i("kang", "执行结果: " + result); // I/kang: 执行结果: 7
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

copyAssetAndWrite方法:

    /**
     * 将 asset 的文件拷贝到缓存中
     */
    public static String copyAssetAndWrite(Context context, String fileName) throws Exception {
        File cacheDir = context.getCacheDir();
        if (!cacheDir.exists()) {
            cacheDir.mkdirs();
        }
        File outFile = new File(cacheDir, fileName);
        if (!outFile.exists()) {
            boolean res = outFile.createNewFile();
            if (res) {
                InputStream is = context.getAssets().open(fileName);
                FileOutputStream fos = new FileOutputStream(outFile);
                byte[] buffer = new byte[is.available()];
                int byteCount;
                while ((byteCount = is.read(buffer)) != -1) {
                    fos.write(buffer, 0, byteCount);
                }
                fos.flush();
                is.close();
                fos.close();
                Toast.makeText(context, "加载成功", Toast.LENGTH_SHORT).show();
                return outFile.getAbsolutePath();
            }
        } else {
            Toast.makeText(context, "文件已存在", Toast.LENGTH_SHORT).show();
        }
        return outFile.getAbsolutePath();
    }

核心思想:拷贝assets目录下的插件APK到本地,创建一个插件APK的DexClassLoader加载它,拿到插件APK里的工具实体类后,运用反射执行插件APK的方法。

在开发的过程中可以直接从网络下载插件APK到本地,然后进行加载反射执行操作

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值