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