feat(cli): add decompilation progress
This commit is contained in:
@@ -42,7 +42,14 @@ public class JadxCLI {
|
||||
jadxArgs.setCodeWriterProvider(SimpleCodeWriter::new);
|
||||
try (JadxDecompiler jadx = new JadxDecompiler(jadxArgs)) {
|
||||
jadx.load();
|
||||
jadx.save();
|
||||
if (LogHelper.getLogLevel() == LogHelper.LogLevelEnum.QUIET) {
|
||||
jadx.save();
|
||||
} else {
|
||||
jadx.save(500, (done, total) -> {
|
||||
int progress = (int) (done * 100.0 / total);
|
||||
System.out.printf("INFO - progress: %d of %d (%d%%)\r", done, total, progress);
|
||||
});
|
||||
}
|
||||
int errorsCount = jadx.getErrorsCount();
|
||||
if (errorsCount != 0) {
|
||||
jadx.printErrorsReport();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package jadx.cli;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.beust.jcommander.IStringConverter;
|
||||
@@ -31,6 +32,8 @@ public class LogHelper {
|
||||
}
|
||||
}
|
||||
|
||||
private static LogLevelEnum logLevelValue;
|
||||
|
||||
public static void setLogLevelFromArgs(JadxCLIArgs args) {
|
||||
if (isCustomLogConfig()) {
|
||||
return;
|
||||
@@ -46,6 +49,8 @@ public class LogHelper {
|
||||
}
|
||||
|
||||
public static void applyLogLevel(LogLevelEnum logLevel) {
|
||||
logLevelValue = logLevel;
|
||||
|
||||
Logger rootLogger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
|
||||
rootLogger.setLevel(logLevel.getLevel());
|
||||
|
||||
@@ -56,6 +61,11 @@ public class LogHelper {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static LogLevelEnum getLogLevel() {
|
||||
return logLevelValue;
|
||||
}
|
||||
|
||||
private static void setLevelForClass(Class<?> cls, Level level) {
|
||||
((Logger) LoggerFactory.getLogger(cls)).setLevel(level);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -162,6 +163,27 @@ public final class JadxDecompiler implements Closeable {
|
||||
save(!args.isSkipSources(), !args.isSkipResources());
|
||||
}
|
||||
|
||||
public interface ProgressListener {
|
||||
void progress(long done, long total);
|
||||
}
|
||||
|
||||
@SuppressWarnings("BusyWait")
|
||||
public void save(int intervalInMillis, ProgressListener listener) {
|
||||
ThreadPoolExecutor ex = (ThreadPoolExecutor) getSaveExecutor();
|
||||
ex.shutdown();
|
||||
try {
|
||||
long total = ex.getTaskCount();
|
||||
while (ex.isTerminating()) {
|
||||
long done = ex.getCompletedTaskCount();
|
||||
listener.progress(done, total);
|
||||
Thread.sleep(intervalInMillis);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
LOG.error("Save interrupted", e);
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
public void saveSources() {
|
||||
save(true, false);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.swing.ProgressMonitor;
|
||||
@@ -66,24 +65,12 @@ public class JadxWrapper {
|
||||
|
||||
public void saveAll(File dir, ProgressMonitor progressMonitor) {
|
||||
Runnable save = () -> {
|
||||
try {
|
||||
decompiler.getArgs().setRootDir(dir);
|
||||
ThreadPoolExecutor ex = (ThreadPoolExecutor) decompiler.getSaveExecutor();
|
||||
ex.shutdown();
|
||||
while (ex.isTerminating()) {
|
||||
long total = ex.getTaskCount();
|
||||
long done = ex.getCompletedTaskCount();
|
||||
progressMonitor.setProgress((int) (done * 100.0 / total));
|
||||
Thread.sleep(500);
|
||||
}
|
||||
progressMonitor.close();
|
||||
LOG.info("decompilation complete, freeing memory ...");
|
||||
decompiler.getClasses().forEach(JavaClass::unload);
|
||||
LOG.info("done");
|
||||
} catch (InterruptedException e) {
|
||||
LOG.error("Save interrupted", e);
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
decompiler.getArgs().setRootDir(dir);
|
||||
decompiler.save(500, (done, total) -> progressMonitor.setProgress((int) (done * 100.0 / total)));
|
||||
progressMonitor.close();
|
||||
LOG.info("decompilation complete, freeing memory ...");
|
||||
decompiler.getClasses().forEach(JavaClass::unload);
|
||||
LOG.info("done");
|
||||
};
|
||||
new Thread(save).start();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user