【问题标题】:dalvik.system.PathClassLoader cannot be cast to java.net.URLClassLoaderdalvik.system.PathClassLoader 无法转换为 java.net.URLClassLoader
【发布时间】:2015-08-10 12:58:37
【问题描述】:

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

【问题讨论】:

    标签: java android urlclassloader dynamic-class-loaders


    【解决方案1】:
    URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader();
    
    ClassLoader.getSystemClassLoader()
    

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

    【讨论】:

      【解决方案2】:

      嘿,这有点晚了,但我遇到了这个问题,并且能够通过创建我自己的 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 上可能为空。

      【讨论】:

        【解决方案3】:

        解决方案是不要假设系统类加载器是URLClassLoader。没有任何地方说它是。如果你的代码曾经成功过,那你就走运了。

        【讨论】:

          猜你喜欢
          • 2020-11-22
          • 1970-01-01
          • 2016-10-19
          • 1970-01-01
          • 2023-02-02
          • 1970-01-01
          • 1970-01-01
          • 2016-06-30
          相关资源
          最近更新 更多