mirror of
https://github.com/revanced/multidexlib2.git
synced 2025-04-29 22:24:28 +02:00
feat: use MemoryDataStore
instead of FileDataStore
This commit is contained in:
parent
ac410e52eb
commit
89a3a37f1d
@ -17,6 +17,7 @@ import java.lang.reflect.UndeclaredThrowableException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
@ -31,7 +32,7 @@ import com.android.tools.smali.dexlib2.iface.ClassDef;
|
||||
import com.android.tools.smali.dexlib2.iface.DexFile;
|
||||
import com.android.tools.smali.dexlib2.writer.DexWriter;
|
||||
import com.android.tools.smali.dexlib2.writer.io.DexDataStore;
|
||||
import com.android.tools.smali.dexlib2.writer.io.FileDataStore;
|
||||
import com.android.tools.smali.dexlib2.writer.io.MemoryDataStore;
|
||||
import com.android.tools.smali.dexlib2.writer.pool.DexPool;
|
||||
|
||||
public class DexIO {
|
||||
@ -65,18 +66,14 @@ public class DexIO {
|
||||
dexPool.writeTo(dataStore);
|
||||
}
|
||||
|
||||
static void writeMultiDexDirectorySingleThread(boolean multiDex, File directory, DexFileNameIterator nameIterator,
|
||||
static void writeMultiDexDirectorySingleThread(Map<String, MemoryDataStore> output, DexFileNameIterator nameIterator,
|
||||
DexFile dexFile, int minMainDexClassCount, boolean minimalMainDex, int maxDexPoolSize, DexIO.Logger logger)
|
||||
throws IOException {
|
||||
Set<? extends ClassDef> classes = dexFile.getClasses();
|
||||
if (!multiDex) {
|
||||
minMainDexClassCount = classes.size();
|
||||
minimalMainDex = false;
|
||||
}
|
||||
Object lock = new Object();
|
||||
//noinspection SynchronizationOnLocalVariableOrMethodParameter
|
||||
synchronized (lock) { // avoid multiple synchronizations in single-threaded mode
|
||||
writeMultiDexDirectoryCommon(directory, nameIterator, Iterators.peekingIterator(classes.iterator()),
|
||||
writeMultiDexDirectoryCommon(output, nameIterator, Iterators.peekingIterator(classes.iterator()),
|
||||
minMainDexClassCount, minimalMainDex, dexFile.getOpcodes(), maxDexPoolSize, logger, lock);
|
||||
}
|
||||
}
|
||||
@ -85,7 +82,7 @@ public class DexIO {
|
||||
|
||||
private static final int PER_THREAD_BATCH_SIZE = 100;
|
||||
|
||||
static void writeMultiDexDirectoryMultiThread(int threadCount, final File directory,
|
||||
static void writeMultiDexDirectoryMultiThread(int threadCount, final Map<String, MemoryDataStore> output,
|
||||
final DexFileNameIterator nameIterator, final DexFile dexFile, final int maxDexPoolSize,
|
||||
final DexIO.Logger logger) throws IOException {
|
||||
Iterator<? extends ClassDef> classIterator = dexFile.getClasses().iterator();
|
||||
@ -99,7 +96,7 @@ public class DexIO {
|
||||
callables.add(new Callable<Void>() {
|
||||
@Override
|
||||
public Void call() throws IOException {
|
||||
writeMultiDexDirectoryCommon(directory, nameIterator, batchedIterator, 0, false,
|
||||
writeMultiDexDirectoryCommon(output, nameIterator, batchedIterator, 0, false,
|
||||
dexFile.getOpcodes(), maxDexPoolSize, logger, lock);
|
||||
return null;
|
||||
}
|
||||
@ -130,7 +127,7 @@ public class DexIO {
|
||||
|
||||
// Common Code
|
||||
|
||||
private static void writeMultiDexDirectoryCommon(File directory, DexFileNameIterator nameIterator,
|
||||
private static void writeMultiDexDirectoryCommon(Map<String, MemoryDataStore> output, DexFileNameIterator nameIterator,
|
||||
PeekingIterator<? extends ClassDef> classIterator, int minMainDexClassCount, boolean minimalMainDex,
|
||||
Opcodes opcodes, int maxDexPoolSize, DexIO.Logger logger, Object lock) throws IOException {
|
||||
do {
|
||||
@ -149,17 +146,17 @@ public class DexIO {
|
||||
classIterator.next();
|
||||
fileClassCount++;
|
||||
}
|
||||
File file;
|
||||
String dexName;
|
||||
MemoryDataStore memoryDataStore = new MemoryDataStore();
|
||||
//noinspection SynchronizationOnLocalVariableOrMethodParameter
|
||||
synchronized (lock) {
|
||||
String name = nameIterator.next();
|
||||
file = new File(directory, name);
|
||||
if (logger != null) logger.log(directory, name, fileClassCount);
|
||||
dexName = nameIterator.next();
|
||||
if (classIterator instanceof BatchedIterator) {
|
||||
((BatchedIterator<?>) classIterator).preloadBatch();
|
||||
}
|
||||
}
|
||||
dexPool.writeTo(new FileDataStore(file));
|
||||
dexPool.writeTo(memoryDataStore);
|
||||
output.put(dexName, memoryDataStore);
|
||||
minMainDexClassCount = 0;
|
||||
minimalMainDex = false;
|
||||
} while (classIterator.hasNext());
|
||||
|
@ -14,11 +14,13 @@ import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.android.tools.smali.dexlib2.Opcodes;
|
||||
import com.android.tools.smali.dexlib2.dexbacked.DexBackedDexFile;
|
||||
import com.android.tools.smali.dexlib2.iface.DexFile;
|
||||
import com.android.tools.smali.dexlib2.iface.MultiDexContainer;
|
||||
import com.android.tools.smali.dexlib2.writer.io.MemoryDataStore;
|
||||
|
||||
public class MultiDexIO {
|
||||
|
||||
@ -65,51 +67,46 @@ public class MultiDexIO {
|
||||
|
||||
// Write
|
||||
|
||||
public static int writeDexFile(boolean multiDex, File file, DexFileNamer namer, DexFile dexFile,
|
||||
public static int writeDexFile(boolean multiDex, Map<String, MemoryDataStore> output, DexFileNamer namer, DexFile dexFile,
|
||||
int maxDexPoolSize, DexIO.Logger logger) throws IOException {
|
||||
return writeDexFile(multiDex, 1, file, namer, dexFile, maxDexPoolSize, logger);
|
||||
return writeDexFile(multiDex, 1, output, namer, dexFile, maxDexPoolSize, logger);
|
||||
}
|
||||
|
||||
public static int writeDexFile(boolean multiDex, int threadCount, File file, DexFileNamer namer, DexFile dexFile,
|
||||
public static int writeDexFile(boolean multiDex, int threadCount, Map<String, MemoryDataStore> output, DexFileNamer namer, DexFile dexFile,
|
||||
int maxDexPoolSize, DexIO.Logger logger) throws IOException {
|
||||
return writeDexFile(multiDex, threadCount, file, namer, dexFile, 0, false, maxDexPoolSize, logger);
|
||||
return writeDexFile(multiDex, threadCount, output, namer, dexFile, 0, false, maxDexPoolSize, logger);
|
||||
}
|
||||
|
||||
public static int writeDexFile(boolean multiDex, File file, DexFileNamer namer, DexFile dexFile,
|
||||
public static int writeDexFile(boolean multiDex, Map<String, MemoryDataStore> output, DexFileNamer namer, DexFile dexFile,
|
||||
int minMainDexClassCount, boolean minimalMainDex, int maxDexPoolSize,
|
||||
DexIO.Logger logger) throws IOException {
|
||||
return writeDexFile(multiDex, 1, file, namer, dexFile, minMainDexClassCount, minimalMainDex, maxDexPoolSize,
|
||||
return writeDexFile(multiDex, 1, output, namer, dexFile, minMainDexClassCount, minimalMainDex, maxDexPoolSize,
|
||||
logger);
|
||||
}
|
||||
|
||||
public static int writeDexFile(boolean multiDex, int threadCount, File file, DexFileNamer namer, DexFile dexFile,
|
||||
public static int writeDexFile(boolean multiDex, int threadCount, Map<String, MemoryDataStore> output, DexFileNamer namer, DexFile dexFile,
|
||||
int minMainDexClassCount, boolean minimalMainDex, int maxDexPoolSize,
|
||||
DexIO.Logger logger) throws IOException {
|
||||
if (file.isDirectory()) {
|
||||
return writeMultiDexDirectory(multiDex, threadCount, file, namer, dexFile, minMainDexClassCount,
|
||||
minimalMainDex, maxDexPoolSize, logger);
|
||||
} else {
|
||||
if (multiDex) throw new UnsupportedOperationException(
|
||||
"Must output to a directory if multi-dex mode is enabled");
|
||||
RawDexIO.writeRawDexFile(file, dexFile, maxDexPoolSize, logger);
|
||||
return 1;
|
||||
}
|
||||
if (!multiDex) throw new UnsupportedOperationException(
|
||||
"Non-multidex is no longer supported, please use the official multidexlib2 for that."
|
||||
);
|
||||
return writeMultiDexDirectory(threadCount, output, namer, dexFile, minMainDexClassCount,
|
||||
minimalMainDex, maxDexPoolSize, logger);
|
||||
}
|
||||
|
||||
public static int writeMultiDexDirectory(boolean multiDex, int threadCount, File directory, DexFileNamer namer,
|
||||
public static int writeMultiDexDirectory(int threadCount, Map<String, MemoryDataStore> output, DexFileNamer namer,
|
||||
DexFile dexFile, int minMainDexClassCount, boolean minimalMainDex, int maxDexPoolSize, DexIO.Logger logger)
|
||||
throws IOException {
|
||||
purgeMultiDexDirectory(multiDex, directory, namer);
|
||||
DexFileNameIterator nameIterator = new DexFileNameIterator(namer);
|
||||
if (threadCount <= 0) {
|
||||
threadCount = Runtime.getRuntime().availableProcessors();
|
||||
if (threadCount > DEFAULT_MAX_THREADS) threadCount = DEFAULT_MAX_THREADS;
|
||||
}
|
||||
if (threadCount > 1 && multiDex && minMainDexClassCount == 0 && !minimalMainDex) {
|
||||
DexIO.writeMultiDexDirectoryMultiThread(threadCount, directory, nameIterator, dexFile, maxDexPoolSize,
|
||||
if (threadCount > 1 && minMainDexClassCount == 0 && !minimalMainDex) {
|
||||
DexIO.writeMultiDexDirectoryMultiThread(threadCount, output, nameIterator, dexFile, maxDexPoolSize,
|
||||
logger);
|
||||
} else {
|
||||
DexIO.writeMultiDexDirectorySingleThread(multiDex, directory, nameIterator, dexFile, minMainDexClassCount,
|
||||
DexIO.writeMultiDexDirectorySingleThread(output, nameIterator, dexFile, minMainDexClassCount,
|
||||
minimalMainDex, maxDexPoolSize, logger);
|
||||
}
|
||||
return nameIterator.getCount();
|
||||
|
Loading…
x
Reference in New Issue
Block a user