Skip to content

Commit

Permalink
Support 5.0、5.1 classesN.dex > 99
Browse files Browse the repository at this point in the history
  • Loading branch information
typ0520 committed Nov 23, 2017
1 parent 99f518b commit 9eeea1d
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 20 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 0.8.2 (2017-11-22)

Features:

- 支持android5.0(api 21)、5.1(api 22)加载超过99个classesN.dex的场景

## 0.8.1 (2017-11-16)

Bugfixes:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Android API 9(2.3)+ ; android-gradle-build 2.0.0+
}
dependencies {
classpath 'com.github.typ0520:fastdex-gradle:0.8.1'
classpath 'com.github.typ0520:fastdex-gradle:0.8.2'
}
}
````
Expand Down
Binary file modified fastdex-gradle/src/main/resources/fastdex-runtime.dex
Binary file not shown.
32 changes: 22 additions & 10 deletions fastdex-runtime/src/main/java/fastdex/runtime/loader/MultiDex.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import android.content.pm.ApplicationInfo;
import android.os.Build;
import android.util.Log;
import dalvik.system.DexFile;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Array;
Expand All @@ -38,6 +38,8 @@
import java.util.regex.Pattern;
import java.util.zip.ZipFile;

import dalvik.system.DexFile;

/**
* MultiDex patches {@link Context#getClassLoader() the application context class
* loader} in order to load classes from more than one dex file. The primary
Expand Down Expand Up @@ -70,8 +72,18 @@ public final class MultiDex {

public static final Set<String> installedApk = new HashSet<String>();

/**
* 4.2 api17 1.6.0
* 5.0 api21 2.1.0
* 5.1 api22 2.1.0
* 6.0 api23 2.1.0
*/
private static final boolean IS_VM_MULTIDEX_CAPABLE =
isVMMultidexCapable(System.getProperty("java.vm.version"));
isVMMultidexCapable(System.getProperty("java.vm.version")) && !is21or22();

public static boolean is21or22() {
return Build.VERSION.SDK_INT == 21 || Build.VERSION.SDK_INT == 22;
}

private MultiDex() {}

Expand Down Expand Up @@ -217,7 +229,7 @@ static boolean isVMMultidexCapable(String versionString) {
}

private static void installSecondaryDexes(ClassLoader loader, File dexDir,
List<? extends File> files)
List<? extends File> files)
throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException,
InvocationTargetException, NoSuchMethodException, IOException {
if (!files.isEmpty()) {
Expand Down Expand Up @@ -296,7 +308,7 @@ private static Method findMethod(Object instance, String name, Class<?>... param
* @param extraElements elements to append at the end of the array.
*/
private static void expandFieldArray(Object instance, String fieldName,
Object[] extraElements) throws NoSuchFieldException, IllegalArgumentException,
Object[] extraElements) throws NoSuchFieldException, IllegalArgumentException,
IllegalAccessException {
Field jlrField = findField(instance, fieldName);
Object[] original = (Object[]) jlrField.get(instance);
Expand Down Expand Up @@ -378,7 +390,7 @@ private static void install(ClassLoader loader,
List<? extends File> additionalClassPathEntries,
File optimizedDirectory)
throws IllegalArgumentException, IllegalAccessException,
NoSuchFieldException, InvocationTargetException, NoSuchMethodException {
NoSuchFieldException, InvocationTargetException, NoSuchMethodException {
/* The patched class loader is expected to be a descendant of
* dalvik.system.BaseDexClassLoader. We modify its
* dalvik.system.DexPathList pathList field to append additional DEX
Expand Down Expand Up @@ -425,7 +437,7 @@ private static Object[] makeDexElements(
Object dexPathList, ArrayList<File> files, File optimizedDirectory,
ArrayList<IOException> suppressedExceptions)
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
NoSuchMethodException {
Method makeDexElements =
findMethod(dexPathList, "makeDexElements", ArrayList.class, File.class,
ArrayList.class);
Expand All @@ -444,7 +456,7 @@ private static void install(ClassLoader loader,
List<? extends File> additionalClassPathEntries,
File optimizedDirectory)
throws IllegalArgumentException, IllegalAccessException,
NoSuchFieldException, InvocationTargetException, NoSuchMethodException {
NoSuchFieldException, InvocationTargetException, NoSuchMethodException {
/* The patched class loader is expected to be a descendant of
* dalvik.system.BaseDexClassLoader. We modify its
* dalvik.system.DexPathList pathList field to append additional DEX
Expand All @@ -463,7 +475,7 @@ private static void install(ClassLoader loader,
private static Object[] makeDexElements(
Object dexPathList, ArrayList<File> files, File optimizedDirectory)
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
NoSuchMethodException {
Method makeDexElements =
findMethod(dexPathList, "makeDexElements", ArrayList.class, File.class);

Expand All @@ -478,7 +490,7 @@ private static final class V4 {
private static void install(ClassLoader loader,
List<? extends File> additionalClassPathEntries)
throws IllegalArgumentException, IllegalAccessException,
NoSuchFieldException, IOException {
NoSuchFieldException, IOException {
/* The patched class loader is expected to be a descendant of
* dalvik.system.DexClassLoader. We modify its
* fields mPaths, mFiles, mZips and mDexs to append additional DEX
Expand All @@ -494,7 +506,7 @@ private static void install(ClassLoader loader,
ZipFile[] extraZips = new ZipFile[extraSize];
DexFile[] extraDexs = new DexFile[extraSize];
for (ListIterator<? extends File> iterator = additionalClassPathEntries.listIterator();
iterator.hasNext();) {
iterator.hasNext();) {
File additionalEntry = iterator.next();
String entryPath = additionalEntry.getAbsolutePath();
path.append(':').append(entryPath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import android.content.pm.ApplicationInfo;
import android.os.Build;
import android.util.Log;

import java.io.BufferedOutputStream;
import java.io.Closeable;
import java.io.File;
Expand All @@ -37,6 +38,7 @@
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

import fastdex.runtime.utils.ZipUtil;

/**
Expand Down Expand Up @@ -95,7 +97,7 @@ public ExtractedDex(File dexDir, String fileName) {
* secondary dex files
*/
static List<? extends File> load(Context context, ApplicationInfo applicationInfo, File dexDir,
boolean forceReload) throws IOException {
boolean forceReload) throws IOException {
Log.i(TAG, "MultiDexExtractor.load(" + applicationInfo.sourceDir + ", " + forceReload + ")");
final File sourceApk = new File(applicationInfo.sourceDir);

Expand Down Expand Up @@ -167,7 +169,10 @@ private static List<ExtractedDex> loadExistingExtractions(
int totalDexNumber = multiDexPreferences.getInt(KEY_DEX_NUMBER, 1);
final List<ExtractedDex> files = new ArrayList<ExtractedDex>(totalDexNumber - 1);

for (int secondaryNumber = 2; secondaryNumber <= totalDexNumber; secondaryNumber++) {



for (int secondaryNumber = getSecondaryNumber(); secondaryNumber <= totalDexNumber; secondaryNumber++) {
String fileName = extractedFilePrefix + secondaryNumber + EXTRACTED_SUFFIX;
ExtractedDex extractedFile = new ExtractedDex(dexDir, fileName);
if (extractedFile.isFile()) {
Expand Down Expand Up @@ -195,6 +200,10 @@ private static List<ExtractedDex> loadExistingExtractions(
return files;
}

private static int getSecondaryNumber() {
return MultiDex.is21or22() ? 100 : 2;
}


/**
* Compare current archive and crc with values stored in {@link SharedPreferences}. Should be
Expand Down Expand Up @@ -241,7 +250,7 @@ private static List<ExtractedDex> performExtractions(File sourceApk, File dexDir
final ZipFile apk = new ZipFile(sourceApk);
try {

int secondaryNumber = 2;
int secondaryNumber = getSecondaryNumber();

ZipEntry dexFile = apk.getEntry(DEX_PREFIX + secondaryNumber + DEX_SUFFIX);
while (dexFile != null) {
Expand Down Expand Up @@ -305,14 +314,14 @@ private static List<ExtractedDex> performExtractions(File sourceApk, File dexDir
* {@link #LOCK_FILENAME}.
*/
private static void putStoredApkInfo(Context context, long timeStamp, long crc,
List<ExtractedDex> extractedDexes) {
List<ExtractedDex> extractedDexes) {
SharedPreferences prefs = getMultiDexPreferences(context);
SharedPreferences.Editor edit = prefs.edit();
edit.putLong(KEY_TIME_STAMP, timeStamp);
edit.putLong(KEY_CRC, crc);
edit.putInt(KEY_DEX_NUMBER, extractedDexes.size() + 1);
edit.putInt(KEY_DEX_NUMBER, extractedDexes.size() + (MultiDex.is21or22() ? 99 : 1));

int extractedDexId = 2;
int extractedDexId = getSecondaryNumber();
for (ExtractedDex dex : extractedDexes) {
edit.putLong(KEY_DEX_CRC + extractedDexId, dex.crc);
edit.putLong(KEY_DEX_TIME + extractedDexId, dex.lastModified());
Expand Down Expand Up @@ -365,7 +374,7 @@ public boolean accept(File pathname) {
}

private static void extract(ZipFile apk, ZipEntry dexFile, File extractTo,
String extractedFilePrefix) throws IOException, FileNotFoundException {
String extractedFilePrefix) throws IOException, FileNotFoundException {

InputStream in = apk.getInputStream(dexFile);
ZipOutputStream out = null;
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
org.gradle.daemon=true

groupId=com.github.typ0520
version=0.8.1
version=0.8.2

ANDROID_BUILD_MIN_SDK_VERSION=14
ANDROID_BUILD_TARGET_SDK_VERSION=22
Expand Down
2 changes: 1 addition & 1 deletion sample/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ buildscript {
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
classpath "me.tatarka:gradle-retrolambda:3.7.0"
classpath 'com.jakewharton:butterknife-gradle-plugin:8.8.1'
classpath 'com.github.typ0520:fastdex-gradle:0.8.1'
classpath 'com.github.typ0520:fastdex-gradle:0.8.2'
}
}

Expand Down

0 comments on commit 9eeea1d

Please sign in to comment.