3

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。什么是解决方案?谢谢,

4

3 回答 3

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

ClassLoader.getSystemClassLoader()

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

于 2017-06-07T03:26:14.203 回答
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 应用程序的类加载器,而不是默认的类加载器。您可以从您的应用程序类 (.getClassLoader()) 中获取它。

  • codeCacheDir我是从我的 ApplicationContext (.getCodeCacheDir().getPath()) 中获得的,尽管在最新版本的 Android 上它可以为空。

于 2020-02-03T22:12:52.303 回答
-2

解决方案不是假设系统类加载器是URLClassLoader. 没有任何地方说它是。如果您的代码曾经有效,那么您很幸运。

于 2017-06-07T04:05:31.713 回答