android studio 2.0一直处于加载,过Android Studio 2.0的即时运行导致DexFile不加载的所有类...

我们可以处理应用程序数据路径中即时运行构建的DEX文件。

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 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);

if (LogUtil.isDebugModeEnable()) {

LogUtil.d("MultiDexHelper",

"getSourcePaths sourceDir=" + applicationInfo.sourceDir + ", dataDir=" + applicationInfo.dataDir);

}

List sourcePaths = new ArrayList();

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);

if (LogUtil.isDebugModeEnable()) {

LogUtil.d("MultiDexHelper", "getSourcePaths totalDexNumber=" + totalDexNumber);

}

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() + "'");

}

}

try {

// handle dex files built by instant run

File instantRunFilePath = new File(applicationInfo.dataDir,

"files" + File.separator + "instant-run" + File.separator + "dex");

if (LogUtil.isDebugModeEnable()) {

LogUtil.d("MultiDexHelper", "getSourcePaths instantRunFile exists=" + instantRunFilePath.exists() + ", isDirectory="

+ instantRunFilePath.isDirectory() + ", getAbsolutePath=" + instantRunFilePath.getAbsolutePath());

}

if (instantRunFilePath.exists() && instantRunFilePath.isDirectory()) {

File[] sliceFiles = instantRunFilePath.listFiles();

for (File sliceFile : sliceFiles) {

if (null != sliceFile && sliceFile.exists() && sliceFile.isFile() && sliceFile.getName().endsWith(".dex")) {

sourcePaths.add(sliceFile.getAbsolutePath());

}

}

}

} catch (Throwable e) {

LogUtil.e("MultiDexHelper", "getSourcePaths parse instantRunFilePath exception", e);

}

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 getAllClasses(Context context) throws PackageManager.NameNotFoundException, IOException {

// List classNames = new ArrayList();

// 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 dexEntries = dexfile.entries();

// while (dexEntries.hasMoreElements()) {

// classNames.add(dexEntries.nextElement());

// }

// } catch (IOException e) {

// throw new IOException("Error at loading dex file '" +

// path + "'");

// }

// }

// return classNames;

// }

/**

* scan parent class's sub classes

*

* @param context

* @param packageName

* @param parentClass

* @param

* @return

*/

public static Set> scanClasses(Context context, String packageName, Class parentClass) {

Set> classes = new HashSet>();

try {

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

for (String path : getSourcePaths(context)) {

if (LogUtil.isDebugModeEnable()) {

LogUtil.d("MultiDexHelper", "scanClasses path=" + path);

}

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 dexEntries = dexfile.entries();

while (dexEntries.hasMoreElements()) {

String className = dexEntries.nextElement();

if (LogUtil.isDebugModeEnable()) {

LogUtil.d("MultiDexHelper", "scanClasses className=" + className);

}

if (className.toLowerCase().startsWith(packageName.toLowerCase())) {

Class clazz = classLoader.loadClass(className);

if (LogUtil.isDebugModeEnable()) {

LogUtil.d("MultiDexHelper",

"scanClasses clazz=" + clazz + ", parentClass=" + parentClass + ", equals=" + clazz

.getSuperclass().equals(parentClass));

}

if (clazz.getSuperclass().equals(parentClass)) {

classes.add(clazz);

}

}

}

} catch (Throwable e) {

LogUtil.e("MultiDexHelper", "scanClasses Error at loading dex file '" +

path + "'", e);

}

}

} catch (Throwable e) {

LogUtil.e("MultiDexHelper", "scanClasses exception", e);

}

return classes;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值