gpt4 book ai didi

Android Multidex 列出所有类

转载 作者:太空狗 更新时间:2023-10-29 16:16:13 26 4
gpt4 key购买 nike

我想使用 ApplicationWrapepr 方法在我的应用程序中使用 multidex,如此处所述 https://plus.google.com/104023661970539138053/posts/YTMf8ADTcFg

我使用了 --minimal-main-dex 选项以及这样的保留文件:

android/support/multidex/ZipUtil.class
android/support/multidex/ZipUtil$CentralDirectory.class
android/support/multidex/MultiDex$V14.class
android/support/multidex/MultiDexExtractor$1.class
android/support/multidex/MultiDexExtractor.class
com/<mypackage>/common/MyApplication.class
com/<mypackage>/common/MyApplicationWrapper.class
com/<mypackage>/common/ui/DashboardActivity.class
android/support/multidex/MultiDexApplication.class
android/support/multidex/MultiDex.class
android/support/multidex/MultiDex$V19.class
android/support/multidex/MultiDex$V4.class

这会在我的主 dex 文件中产生列出的类,这没问题。我不是使用一个库,该库使用以下代码列出 dexfile 中的所有类,但只获取主要“clesses.dex”的条目,而不是所有其他加载的 dex 文件的条目,因为新的 DexFile 仅检查“classes.dex” :

private static List<String> getPaths(final String[] sourcePaths) {
List<String> result = new ArrayList<String>();

for (String s : sourcePaths) {
try {
DexFile dexfile = new DexFile(s);
Enumeration<String> entries = dexfile.entries();

while (entries.hasMoreElements()) {
result.add(entries.nextElement());
}
} catch (IOException ioe) {
Log.w(TAG, "cannot open file=" + s + ";Exception=" + ioe.getMessage());
}
}

return result;
}

目前单一路径由以下内容确定:

application.getApplicationContext().getApplicationInfo().sourceDir;

结果类似于/data/../myapplicationname.apk

是否有另一种可能性来列出 dex 文件中的所有类?或者当前在类加载器中的所有类?该库对项目至关重要,并使用这种方法稍后通过反射查找组件实现。

编辑 1:如果发现classes2.dex文件放在: /data/data/com./code_cache/secondary-dexes/com.-1.apk.classes2.dex

然而,当使用带有此路径的 new DexFile() 时,会抛出 IOEsxception 并显示消息“无法打开 dexfile”。

最佳答案

DexFile 接受 zip/apk 文件的路径,并提取它以找到 .dex 文件。因此,如果您使用 .dex 作为路径,它将引发错误。

Google 也发表了一篇文章 Building Apps with Over 65K Methods解决 --multi-dex 问题。

我写了一个类来加载所有的类。您可以在以下位置阅读更多信息:http://xudshen.info/2014/11/12/list-all-classes-after-multidex/

import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Build;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import dalvik.system.DexFile;

/**
* Created by xudshen@hotmail.com on 14/11/13.
*/
public class MultiDexHelper {
private static final String EXTRACTED_NAME_EXT = ".classes";
private static final String EXTRACTED_SUFFIX = ".zip";

private static final String SECONDARY_FOLDER_NAME = "code_cache" + File.separator +
"secondary-dexes";

private static final String PREFS_FILE = "multidex.version";
private static final String KEY_DEX_NUMBER = "dex.number";

private static SharedPreferences getMultiDexPreferences(Context context) {
return context.getSharedPreferences(PREFS_FILE,
Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB
? Context.MODE_PRIVATE
: Context.MODE_PRIVATE | Context.MODE_MULTI_PROCESS);
}

/**
* get all the dex path
*
* @param context the application context
* @return all the dex path
* @throws PackageManager.NameNotFoundException
* @throws IOException
*/
public static List<String> getSourcePaths(Context context) throws PackageManager.NameNotFoundException, IOException {
ApplicationInfo applicationInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), 0);
File sourceApk = new File(applicationInfo.sourceDir);
File dexDir = new File(applicationInfo.dataDir, SECONDARY_FOLDER_NAME);

List<String> sourcePaths = new ArrayList<String>();
sourcePaths.add(applicationInfo.sourceDir); //add the default apk path

//the prefix of extracted file, ie: test.classes
String extractedFilePrefix = sourceApk.getName() + EXTRACTED_NAME_EXT;
//the total dex numbers
int totalDexNumber = getMultiDexPreferences(context).getInt(KEY_DEX_NUMBER, 1);

for (int secondaryNumber = 2; secondaryNumber <= totalDexNumber; secondaryNumber++) {
//for each dex file, ie: test.classes2.zip, test.classes3.zip...
String fileName = extractedFilePrefix + secondaryNumber + EXTRACTED_SUFFIX;
File extractedFile = new File(dexDir, fileName);
if (extractedFile.isFile()) {
sourcePaths.add(extractedFile.getAbsolutePath());
//we ignore the verify zip part
} else {
throw new IOException("Missing extracted secondary dex file '" +
extractedFile.getPath() + "'");
}
}

return sourcePaths;
}

/**
* get all the classes name in "classes.dex", "classes2.dex", ....
*
* @param context the application context
* @return all the classes name
* @throws PackageManager.NameNotFoundException
* @throws IOException
*/
public static List<String> getAllClasses(Context context) throws PackageManager.NameNotFoundException, IOException {
List<String> classNames = new ArrayList<String>();
for (String path : getSourcePaths(context)) {
try {
DexFile dexfile = null;
if (path.endsWith(EXTRACTED_SUFFIX)) {
//NOT use new DexFile(path), because it will throw "permission error in /data/dalvik-cache"
dexfile = DexFile.loadDex(path, path + ".tmp", 0);
} else {
dexfile = new DexFile(path);
}
Enumeration<String> dexEntries = dexfile.entries();
while (dexEntries.hasMoreElements()) {
classNames.add(dexEntries.nextElement());
}
} catch (IOException e) {
throw new IOException("Error at loading dex file '" +
path + "'");
}
}
return classNames;
}
}

关于Android Multidex 列出所有类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26623905/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com