{"id":972,"date":"2023-03-11T20:16:21","date_gmt":"2023-03-11T12:16:21","guid":{"rendered":"https:\/\/www.appblog.cn\/?p=972"},"modified":"2023-04-29T13:26:53","modified_gmt":"2023-04-29T05:26:53","slug":"difference-between-dexclassloader-and-pathclassloader-in-android","status":"publish","type":"post","link":"https:\/\/www.appblog.cn\/index.php\/2023\/03\/11\/difference-between-dexclassloader-and-pathclassloader-in-android\/","title":{"rendered":"Android\u4e2dDexClassLoader\u548cPathClassLoader\u7684\u533a\u522b"},"content":{"rendered":"<p>\u5728\u4f7f\u7528Java\u865a\u62df\u673a\u65f6\uff0c\u6211\u4eec\u7ecf\u5e38\u81ea\u5b9a\u4e49\u7ee7\u627f\u81eaClassLoader\u7684\u7c7b\u52a0\u8f7d\u5668\u3002\u7136\u540e\u901a\u8fc7defineClass\u65b9\u6cd5\u6765\u4ece\u4e00\u4e2a\u4e8c\u8fdb\u5236\u6d41\u4e2d\u52a0\u8f7dClass\u3002\u800c\u5728Android\u4e2d\u6211\u4eec\u65e0\u6cd5\u8fd9\u4e48\u4f7f\u7528\uff0cAndroid\u4e2dClassLoader\u7684defineClass\u65b9\u6cd5\u5177\u4f53\u662f\u8c03\u7528VMClassLoader\u7684defineClass\u672c\u5730\u9759\u6001\u65b9\u6cd5\u3002\u800c\u8fd9\u4e2a\u672c\u5730\u65b9\u6cd5\u4ec0\u4e48\u90fd\u6ca1\u505a\uff0c\u53ea\u662f\u629b\u51fa\u4e86\u4e00\u4e2a<code>UnsupportedOperationException<\/code>\u5f02\u5e38\u3002 <\/p>\n<p>\u65e2\u7136\u5728Dalvik\u865a\u62df\u673a\u91cc\uff0cClassLoader\u4e0d\u597d\u7528\uff0c\u90a3\u4e48Android\u5b98\u65b9\u4e3a\u4e86\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\uff0c\u4eceClassLoader\u4e2d\u6d3e\u751f\u51fa\u4e86\u4e24\u4e2a\u7c7b\uff1aDexClassLoader\u548cPathClassLoader\u3002<\/p>\n<p><!-- more --><\/p>\n<h2>DexClassLoader<\/h2>\n<pre><code class=\"language-java\">public DexClassLoader(String dexPath, String dexOutputDir, String libPath, ClassLoader parent)<\/code><\/pre>\n<p>\u53c2\u6570\u8be6\u89e3\uff1a<\/p>\n<ul>\n<li>dexPath\uff1adex\u6587\u4ef6\u8def\u5f84\u5217\u8868\uff0c\u591a\u4e2a\u8def\u5f84\u4f7f\u7528\u201d:\u201d\u5206\u9694<\/li>\n<li>dexOutputDir\uff1a\u7ecf\u8fc7\u4f18\u5316\u7684dex\u6587\u4ef6\uff08odex\uff09\u6587\u4ef6\u8f93\u51fa\u76ee\u5f55<\/li>\n<li>libPath\uff1a\u52a8\u6001\u5e93\u8def\u5f84\uff08\u5c06\u88ab\u6dfb\u52a0\u5230app\u52a8\u6001\u5e93\u641c\u7d22\u8def\u5f84\u5217\u8868\u4e2d\uff09<\/li>\n<li>parent\uff1a\u8fd9\u662f\u4e00\u4e2aClassLoader\uff0c\u8fd9\u4e2a\u53c2\u6570\u7684\u4e3b\u8981\u4f5c\u7528\u662f\u4fdd\u7559java\u4e2dClassLoader\u7684\u59d4\u6258\u673a\u5236\uff08\u4f18\u5148\u7236\u7c7b\u52a0\u8f7d\u5668\u52a0\u8f7dclasses\uff0c\u7531\u4e0a\u800c\u4e0b\u7684\u52a0\u8f7d\u673a\u5236\uff0c\u9632\u6b62\u91cd\u590d\u52a0\u8f7d\u7c7b\u5b57\u8282\u7801\uff09<\/li>\n<\/ul>\n<p>DexClassLoader\u662f\u4e00\u4e2a\u53ef\u4ee5\u4ece\u5305\u542bclasses.dex\u5b9e\u4f53\u7684.jar\u6216.apk\u6587\u4ef6\u4e2d\u52a0\u8f7dclasses\u7684\u7c7b\u52a0\u8f7d\u5668\u3002\u53ef\u4ee5\u7528\u4e8e\u5b9e\u73b0dex\u7684\u52a8\u6001\u52a0\u8f7d\u3001\u4ee3\u7801\u70ed\u66f4\u65b0\u7b49\u7b49\u3002\u8fd9\u4e2a\u7c7b\u52a0\u8f7d\u5668\u5fc5\u987b\u8981\u4e00\u4e2aapp\u7684\u79c1\u6709\u3001\u53ef\u5199\u76ee\u5f55\u6765\u7f13\u5b58\u7ecf\u8fc7\u4f18\u5316\u7684classes\uff08odex\u6587\u4ef6\uff09\uff0c\u4f7f\u7528<code>Context.getDir(String, int)<\/code>\u65b9\u6cd5\u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u8fd9\u6837\u7684\u76ee\u5f55\uff0c\u4f8b\u5982\uff1a<\/p>\n<pre><code class=\"language-java\">File dexOutputDir = context.getDir(&#039;dex&#039;, 0);<\/code><\/pre>\n<h2>PathClassLoader<\/h2>\n<p>PathClassLoader\u63d0\u4f9b\u4e24\u4e2a\u5e38\u7528\u6784\u9020\u65b9\u6cd5<\/p>\n<pre><code class=\"language-java\">public PathClassLoader (String path, ClassLoader parent)<\/code><\/pre>\n<pre><code class=\"language-java\">public PathClassLoader (String path, String libPath, ClassLoader parent)<\/code><\/pre>\n<p>\u53c2\u6570\u8be6\u89e3\uff1a<\/p>\n<ul>\n<li>path\uff1a\u6587\u4ef6\u6216\u8005\u76ee\u5f55\u7684\u5217\u8868<\/li>\n<li>libPath\uff1a\u5305\u542blib\u5e93\u7684\u76ee\u5f55\u5217\u8868<\/li>\n<li>parent\uff1a\u7236\u7c7b\u52a0\u8f7d\u5668<\/li>\n<\/ul>\n<p>PathClassLoader\u63d0\u4f9b\u4e00\u4e2a\u7b80\u5355\u7684ClassLoader\u5b9e\u73b0\uff0c\u53ef\u4ee5\u64cd\u4f5c\u5728\u672c\u5730\u6587\u4ef6\u7cfb\u7edf\u7684\u6587\u4ef6\u5217\u8868\u6216\u76ee\u5f55\u4e2d\u7684classes\uff0c\u4f46\u4e0d\u53ef\u4ee5\u4ece\u7f51\u7edc\u4e2d\u52a0\u8f7dclasses\u3002<\/p>\n<h2>DexClassLoader\u548cPathClassLoader\u7684\u533a\u522b<\/h2>\n<p>\u4e3a\u4e86\u4fbf\u4e8e\u7406\u89e3\uff0c\u6211\u4eec\u67e5\u770b\u4e00\u4e0b\u4e8c\u8005\u7684\u6e90\u7801\uff1a<\/p>\n<pre><code class=\"language-java\">\/\/ DexClassLoader.java\npublic class DexClassLoader extends BaseDexClassLoader {\n    public DexClassLoader(String dexPath, String optimizedDirectory,\n            String libraryPath, ClassLoader parent) {\n        super(dexPath, new File(optimizedDirectory), libraryPath, parent);\n    }\n}<\/code><\/pre>\n<pre><code class=\"language-java\">\/\/ PathClassLoader.java\npublic class PathClassLoader extends BaseDexClassLoader {\n    public PathClassLoader(String dexPath, ClassLoader parent) {\n        super(dexPath, null, null, parent);\n    }\n\n    public PathClassLoader(String dexPath, String libraryPath,\n            ClassLoader parent) {\n        super(dexPath, null, libraryPath, parent);\n    }\n}<\/code><\/pre>\n<p>\u5f88\u660e\u663e\u4e24\u8005\u90fd\u7ee7\u627f\u4e8eBaseDexClassLoader\u7c7b\uff0c\u5e76\u505a\u4e86\u4e00\u4e0b\u5c01\u88c5\uff0c\u5177\u4f53\u7684\u5b9e\u73b0\u8fd8\u662f\u5728\u7236\u7c7b\u91cc\u3002\u4e0d\u96be\u770b\u51fa\uff0c\u4e3b\u8981\u7684\u533a\u522b\u5728\u4e8ePathClassLoader\u7684optimizedDirectory\u53c2\u6570\u53ea\u80fd\u662fnull\uff0c\u90a3\u4e48optimizedDirectory\u662f\u505a\u4ec0\u4e48\u7528\u7684\u5462\uff1f\u6211\u4eec\u8fdbBaseDexClassLoader\u53bb\u770b\u770b\u8fd9\u4e2a\u53c2\u6570\u3002<\/p>\n<pre><code class=\"language-java\">public BaseDexClassLoader(String dexPath, File optimizedDirectory,\n        String libraryPath, ClassLoader parent) {\n    super(parent);\n    this.originalPath = dexPath;\n    this.pathList = new DexPathList(this, dexPath, libraryPath, optimizedDirectory);\n}<\/code><\/pre>\n<p>\u4ee3\u7801\u4e2d\u4e0eoptimizedDirectory\u6709\u5173\u7684\u5730\u65b9\u662fnew\u4e00\u4e2aDexPathList\u5b9e\u4f8b\u3002<\/p>\n<pre><code class=\"language-java\">public DexPathList(ClassLoader definingContext, String dexPath,\n        String libraryPath, File optimizedDirectory) {\n    \u2026\u2026\n    this.dexElements = makeDexElements(splitDexPath(dexPath), optimizedDirectory);\n}\n\nprivate static Element[] makeDexElements(ArrayList&lt;File&gt; files,\n        File optimizedDirectory) {\n    ArrayList&lt;Element&gt; elements = new ArrayList&lt;Element&gt;();\n    for (File file : files) {\n        ZipFile zip = null;\n        DexFile dex = null;\n        String name = file.getName();\n        if (name.endsWith(DEX_SUFFIX)) {\n            dex = loadDexFile(file, optimizedDirectory);\n        } else if (name.endsWith(APK_SUFFIX) || name.endsWith(JAR_SUFFIX)\n                || name.endsWith(ZIP_SUFFIX)) {\n            zip = new ZipFile(file);\n        }\n        \u2026\u2026\n        if ((zip != null) || (dex != null)) {\n            elements.add(new Element(file, zip, dex));\n        }\n    }\n    return elements.toArray(new Element[elements.size()]);\n}\n\nprivate static DexFile loadDexFile(File file, File optimizedDirectory)\n        throws IOException {\n    if (optimizedDirectory == null) {\n        return new DexFile(file);\n    } else {\n        String optimizedPath = optimizedPathFor(file, optimizedDirectory);\n        return DexFile.loadDex(file.getPath(), optimizedPath, 0);\n    }\n}\n\n\/**\n * Converts a dex\/jar file path and an output directory to an\n * output file path for an associated optimized dex file.\n *\/\nprivate static String optimizedPathFor(File path,\n        File optimizedDirectory) {\n    String fileName = path.getName();\n    if (!fileName.endsWith(DEX_SUFFIX)) {\n        int lastDot = fileName.lastIndexOf(&quot;.&quot;);\n        if (lastDot &lt; 0) {\n            fileName += DEX_SUFFIX;\n        } else {\n            StringBuilder sb = new StringBuilder(lastDot + 4);\n            sb.append(fileName, 0, lastDot);\n            sb.append(DEX_SUFFIX);\n            fileName = sb.toString();\n        }\n    }\n    File result = new File(optimizedDirectory, fileName);\n    return result.getPath();\n}<\/code><\/pre>\n<p>optimizedDirectory\u662f\u7528\u6765\u7f13\u5b58\u6211\u4eec\u9700\u8981\u52a0\u8f7d\u7684dex\u6587\u4ef6\u7684\uff0c\u5e76\u521b\u5efa\u4e00\u4e2aDexFile\u5bf9\u8c61\uff0c\u5982\u679c\u5b83\u4e3anull\uff0c\u90a3\u4e48\u4f1a\u76f4\u63a5\u4f7f\u7528dex\u6587\u4ef6\u539f\u6709\u7684\u8def\u5f84\u6765\u521b\u5efaDexFile<br \/>\n\u5bf9\u8c61\u3002<\/p>\n<p>optimizedDirectory\u5fc5\u987b\u662f\u4e00\u4e2a\u5185\u90e8\u5b58\u50a8\u8def\u5f84\uff0c\u65e0\u8bba\u54ea\u79cd\u52a8\u6001\u52a0\u8f7d\uff0c\u52a0\u8f7d\u7684\u53ef\u6267\u884c\u6587\u4ef6\u4e00\u5b9a\u8981\u5b58\u653e\u5728\u5185\u90e8\u5b58\u50a8\u3002DexClassLoader\u53ef\u4ee5\u6307\u5b9a\u81ea\u5df1\u7684optimizedDirectory\uff0c\u6240\u4ee5\u5b83\u53ef\u4ee5\u52a0\u8f7d\u5916\u90e8\u7684dex\uff0c\u56e0\u4e3a\u8fd9\u4e2adex\u4f1a\u88ab\u590d\u5236\u5230\u5185\u90e8\u8def\u5f84\u7684optimizedDirectory\uff1b\u800cPathClassLoader\u6ca1\u6709optimizedDirectory\uff0c\u6240\u4ee5\u5b83\u53ea\u80fd\u52a0\u8f7d\u5185\u90e8\u7684dex\uff0c\u8fd9\u4e9b\u5927\u90fd\u662f\u5b58\u5728\u7cfb\u7edf\u4e2d\u5df2\u7ecf\u5b89\u88c5\u8fc7\u7684apk\u91cc\u9762\u7684\u3002<\/p>\n<p>\u901a\u8fc7\u4ee5\u4e0a\u7684\u5206\u6790\uff0c\u6211\u4eec\u53ef\u4ee5\u5f97\u51fa\u4e8c\u8005\u529f\u80fd\u4e0a\u7684\u533a\u522b<\/p>\n<blockquote>\n<p>DexClassLoader\uff1a\u80fd\u591f\u52a0\u8f7d\u672a\u5b89\u88c5\u7684jar\/apk\/dex<br \/>\nPathClassLoader\uff1a\u53ea\u80fd\u52a0\u8f7d\u7cfb\u7edf\u4e2d\u5df2\u7ecf\u5b89\u88c5\u8fc7\u7684apk<\/p>\n<\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>\u5728\u4f7f\u7528Java\u865a\u62df\u673a\u65f6\uff0c\u6211\u4eec\u7ecf\u5e38\u81ea\u5b9a\u4e49\u7ee7\u627f\u81eaClassLoader\u7684\u7c7b\u52a0\u8f7d\u5668\u3002\u7136\u540e\u901a\u8fc7defineClass\u65b9 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[61],"tags":[266],"class_list":["post-972","post","type-post","status-publish","format-standard","hentry","category-android-basic","tag-classloader"],"_links":{"self":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts\/972","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/comments?post=972"}],"version-history":[{"count":0,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/posts\/972\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/media?parent=972"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/categories?post=972"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.appblog.cn\/index.php\/wp-json\/wp\/v2\/tags?post=972"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}