Replugin 插件中MutliDex 分多包 后加载插件报错的问题解决

Caused by: java.lang.ClassNotFoundException: Didn’t find class “com.qihoo360.replugin.Entry” on path: DexPathList[[zip file “/data/app/com.topdraw.replugintest2-1/base.apk”],nativeLibraryDirectories=[/data/app/com.topdraw.replugintest2-1/lib/x86, /system/lib, /vendor/lib]]

    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)

    at com.qihoo360.replugin.RePluginClassLoader.findClass(RePluginClassLoader.java:176)

    at java.lang.ClassLoader.loadClass(ClassLoader.java:380)

    at com.qihoo360.replugin.RePluginClassLoader.loadClass(RePluginClassLoader.java:167)

    at java.lang.reflect.Method.invoke(Native Method) 

    at com.qihoo360.replugin.PluginDexClassLoader.loadClassFromHost(PluginDexClassLoader.java:158) 

    at com.qihoo360.replugin.PluginDexClassLoader.loadClass(PluginDexClassLoader.java:141) 

    at java.lang.ClassLoader.loadClass(ClassLoader.java:312) 

    at com.qihoo360.loader2.Loader.loadEntryMethod3(Loader.java:481) 

    at com.qihoo360.loader2.Plugin.loadEntryLocked(Plugin.java:878) 

    at com.qihoo360.loader2.Plugin.doLoad(Plugin.java:832) 

    at com.qihoo360.loader2.Plugin.tryLoadAgain(Plugin.java:757) 

    at com.qihoo360.loader2.Plugin.loadLocked(Plugin.java:703) 

    at com.qihoo360.loader2.Plugin.load(Plugin.java:444) 

    at com.qihoo360.loader2.PmBase.loadPlugin(PmBase.java:1166) 

    at com.qihoo360.loader2.PmBase.loadAppPlugin(PmBase.java:1151) 

    at com.qihoo360.loader2.PluginCommImpl.getActivityInfo(PluginCommImpl.java:561) 

    at com.qihoo360.loader2.PluginCommImpl.loadPluginActivity(PluginCommImpl.java:411) 

    at com.qihoo360.loader2.PluginLibraryInternalProxy.startActivity(PluginLibraryInternalProxy.java:268) 

    at com.qihoo360.loader2.PluginCommImpl.startActivity(PluginCommImpl.java:380) 

    at com.qihoo360.i.Factory.startActivityWithNoInjectCN(Factory.java:327) 

    at com.qihoo360.replugin.RePlugin.startActivity(RePlugin.java:249) 

    at com.topdraw.replugintest2.MainActivity$1.onClick(MainActivity.java:32) 

    at android.view.View.performClick(View.java:5610) 

    at android.view.View$PerformClick.run(View.java:22265) 

    at android.os.Handler.handleCallback(Handler.java:751) 

    at android.os.Handler.dispatchMessage(Handler.java:95) 

    at android.os.Looper.loop(Looper.java:154) 

    at android.app.ActivityThread.main(ActivityThread.java:6077) 
    这个报错 我在android6,7  还有5.0以下都有问题
    但是在小米12 上没问题

网上有些这类方法的解决方案是不对的,大概是通过给主class.dex. 添加报错的的class来实现的,
这个的根本原因是com.qihoo360.replugin.PluginDexClassLoader
installMultiDexesBeforeLollipop 这个方法中

private void installMultiDexesBeforeLollipop(PluginInfo pi, String dexPath, ClassLoader parent) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            return;
        }

        try {

            // get paths of extra dex
            List<File> dexFiles = getExtraDexFiles(pi, dexPath);

            if (dexFiles != null && dexFiles.size() > 0) {

                List<Object[]> allElements = new LinkedList<>();

                // get dexElements of main dex
                //下面这个代码有问题
                //改为:Class<?> clz = getClass()
             //直接在本classLoader中添加dex中的class
             //这个我测试是ok了的 
                Class<?> clz = Class.forName("dalvik.system.BaseDexClassLoader");
                Object pathList = ReflectUtils.readField(clz, this, "pathList");
                Object[] mainElements = (Object[]) ReflectUtils.readField(pathList.getClass(), pathList, "dexElements");
                allElements.add(mainElements);

                // get dexElements of extra dex (need to load dex first)
                String optimizedDirectory = pi.getExtraOdexDir().getAbsolutePath();

                for (File file : dexFiles) {
                    if (LogDebug.LOG && RePlugin.getConfig().isPrintDetailLog()) {
                        LogDebug.d(TAG, "dex file:" + file.getName());
                    }

                    DexClassLoader dexClassLoader = new DexClassLoader(file.getAbsolutePath(), optimizedDirectory, optimizedDirectory, parent);

                    Object obj = ReflectUtils.readField(clz, dexClassLoader, "pathList");
                    Object[] dexElements = (Object[]) ReflectUtils.readField(obj.getClass(), obj, "dexElements");
                    allElements.add(dexElements);
                }

                // combine Elements
                Object combineElements = combineArray(allElements);

                // rewrite Elements combined to classLoader
                ReflectUtils.writeField(pathList.getClass(), pathList, "dexElements", combineElements);

                // delete extra dex, after optimized
                FileUtils.forceDelete(pi.getExtraDexDir());

                //Test whether the Extra Dex is installed
                if (LogDebug.LOG && RePlugin.getConfig().isPrintDetailLog()) {

                    Object object = ReflectUtils.readField(pathList.getClass(), pathList, "dexElements");
                    int length = Array.getLength(object);
                    LogDebug.d(TAG, "dexElements length:" + length);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

解决方法在注释中写了,由于这个很多人是通过gradle 依赖的远程仓库的,无法改源码,我是通过源码改了之后 ,本地编译,gradle 通过本地引入这个仓库代码解决的
工程的gradle中

   maven{
            url uri('./plugin')
        }
        maven{
            url uri('../plugin')
        }

工程根目录创建plugin文件夹
然后把编译成的pom文件拷本进去,这个自己下载源码编译,就可以了,包括插件和library库
在这里插入图片描述

编译过程:
分别打开源码中的插件工程 和lib工程
执行gradle task中的uploadArchives 就可以在对应目录成功了,

  uploadArchives {
       repositories.mavenDeployer {
       //这个是本地生产的目录
           repository(url: "file://${System.getenv('HOME')}/.m2/repository")
           pom.groupId = theGroup
           pom.version = version
           pom.artifactId = pbArtifactId
       }
    }

如果还有相关问题可以留言

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值