From 89a3a37f1dceb1769e294342abefadd1f89892be Mon Sep 17 00:00:00 2001 From: oSumAtrIX Date: Fri, 11 Aug 2023 02:10:46 +0200 Subject: [PATCH] feat: use `MemoryDataStore` instead of `FileDataStore` --- src/main/java/lanchon/multidexlib2/DexIO.java | 27 ++++++------- .../java/lanchon/multidexlib2/MultiDexIO.java | 39 +++++++++---------- 2 files changed, 30 insertions(+), 36 deletions(-) diff --git a/src/main/java/lanchon/multidexlib2/DexIO.java b/src/main/java/lanchon/multidexlib2/DexIO.java index 97227f6..c60df56 100644 --- a/src/main/java/lanchon/multidexlib2/DexIO.java +++ b/src/main/java/lanchon/multidexlib2/DexIO.java @@ -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 output, DexFileNameIterator nameIterator, DexFile dexFile, int minMainDexClassCount, boolean minimalMainDex, int maxDexPoolSize, DexIO.Logger logger) throws IOException { Set 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 output, final DexFileNameIterator nameIterator, final DexFile dexFile, final int maxDexPoolSize, final DexIO.Logger logger) throws IOException { Iterator classIterator = dexFile.getClasses().iterator(); @@ -99,7 +96,7 @@ public class DexIO { callables.add(new Callable() { @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 output, DexFileNameIterator nameIterator, PeekingIterator 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()); diff --git a/src/main/java/lanchon/multidexlib2/MultiDexIO.java b/src/main/java/lanchon/multidexlib2/MultiDexIO.java index 0815493..7310db8 100644 --- a/src/main/java/lanchon/multidexlib2/MultiDexIO.java +++ b/src/main/java/lanchon/multidexlib2/MultiDexIO.java @@ -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 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 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 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 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 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();