dalvik.system.PathClassLoader无法强制转换为java.net.URLClassLoader

时间:2015-08-10 12:58:37

标签: java android urlclassloader dynamic-class-loaders

Android - 将jar文件动态添加到ClassLoader,如:

String strJarfile = "/data/data/com.example.classloader/files/apps/Calc/SumAndSub.jar";    
URLClassLoader sysloader = (URLClassLoader) ClassLoader
                .getSystemClassLoader();
        try
        {
            File f = new File(strJarfile);
            URL u = f.toURI().toURL();

            Class[] parameters = new Class[] { URL.class };
            Method method = URLClassLoader.class.getDeclaredMethod("addURL",
                    parameters);
            method.setAccessible(true);
            method.invoke(sysloader, new Object[] { u });
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

而且,错误:

Caused by: java.lang.ClassCastException: dalvik.system.PathClassLoader cannot be cast to java.net.URLClassLoader

此代码在java-core中运行良好,但不适用于android。 什么是解决方案? 谢谢,

3 个答案:

答案 0 :(得分:0)

URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader();

ClassLoader.getSystemClassLoader()

会将PathClassLoader作为ClassLoader返回,因此(URLClassLoader)会导致异常。

答案 1 :(得分:0)

嘿,这有点晚了,但是我遇到了麻烦,并且能够通过创建自己的DexClassLoader来解决它。这是一个现在对我有用的示例函数:

private SomeClass loadSomeClassInJarFile(String pathToJar, String mainClassName, String codeCacheDir) {
    SomeClass instanceOfSomeClass = null;
    try {
        DexClassLoader classLoader = new DexClassLoader(
                                            pathToJar, 
                                            codeCacheDir, 
                                            null, 
                                            mClassLoader);

        Class<?> cls = classLoader.loadClass(mainClassName);
        Constructor<?> cs = cls.getConstructor();
        instanceOfSomeClass = (SomeClass) cs.newInstance();
    } catch (Exception ex) {
        // This isn't the right class
        Log.w(Tag, "Class " + mainClassName + " could not load because " + ex.getMessage());
    }

    return instanceOfSomeClass;
}

关于上述内容的几点注意事项:

  • mClassLoader 必须是您的Android应用程序中的类加载器,而不是默认的类加载器。您可以从Application类(.getClassLoader())中获取它。

  • 我从我的ApplicationContext(.getCodeCacheDir()。getPath())中获得了
  • codeCacheDir ,尽管在​​更新的Android版本中它可以为null。

答案 2 :(得分:-1)

解决方案不是假设系统类加载器是URLClassLoader。没有任何地方可以说它是。如果你的代码有效,你就很幸运。