android 打开apk慢,Android Multidex导致的App启动缓慢

public class MultiDexUtils {

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

final   ApplicationInfo applicationInfo =   context.getPackageManager().getApplicationInfo(context.getPackageName(), 0);

final   File sourceApk = new File(applicationInfo.sourceDir);

final   File dexDir = new File(applicationInfo.dataDir, SECONDARY_FOLDER_NAME);

final   List sourcePaths = new ArrayList<>();

sourcePaths.add(applicationInfo.sourceDir);   //add the default apk path

//the   prefix of extracted file, ie: test.classes

final   String extractedFilePrefix = sourceApk.getName() + EXTRACTED_NAME_EXT;

//the   total dex numbers

final   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...

final   String fileName = extractedFilePrefix + secondaryNumber + EXTRACTED_SUFFIX;

final   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 external classes name in "classes2.dex",   "classes3.dex" ....

*

-   @param context the application context

-   @return all the classes name in the external dex

-   @throws PackageManager.NameNotFoundException

-   @throws IOException

*/

public List   getExternalDexClasses(Context context) throws PackageManager.NameNotFoundException,   IOException {

final   List paths = getSourcePaths(context);

if(paths.size()   <= 1) {

//   no external dex

return   null;

}

//   the first element is the main dex, remove it.

paths.remove(0);

final   List classNames = new ArrayList<>();

for   (String path : paths) {

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

}

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

}

/**

-   Get all loaded external classes name in "classes2.dex",   "classes3.dex" ....

-   @param context

-   @return get all loaded external classes

*/

public List   getLoadedExternalDexClasses(Context context) {

try   {

final   List externalDexClasses = getExternalDexClasses(context);

if   (externalDexClasses != null && !externalDexClasses.isEmpty()) {

final   ArrayList classList = new ArrayList<>();

final   java.lang.reflect.Method m = ClassLoader.class.getDeclaredMethod("findLoadedClass",   new Class[]{String.class});

m.setAccessible(true);

final   ClassLoader cl = context.getClassLoader();

for   (String clazz : externalDexClasses) {

if   (m.invoke(cl, clazz) != null) {

classList.add(clazz.replaceAll("\\.",   "/").replaceAll("$", ".class"));

}

}

return   classList;

}

}   catch (Exception e) {

e.printStackTrace();

}

return   null;

}

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值