fix(gui): use correct threads for code from close and reload actions (#2684)
This commit is contained in:
@@ -21,13 +21,13 @@ import jadx.api.metadata.ICodeNodeRef;
|
||||
import jadx.core.dex.nodes.RootNode;
|
||||
import jadx.core.utils.Utils;
|
||||
import jadx.core.utils.exceptions.JadxRuntimeException;
|
||||
import jadx.gui.jobs.LoadTask;
|
||||
import jadx.gui.treemodel.JClass;
|
||||
import jadx.gui.treemodel.JNode;
|
||||
import jadx.gui.treemodel.JPackage;
|
||||
import jadx.gui.treemodel.JRoot;
|
||||
import jadx.gui.ui.MainWindow;
|
||||
import jadx.gui.utils.JNodeCache;
|
||||
import jadx.gui.utils.NLS;
|
||||
import jadx.gui.utils.UiUtils;
|
||||
|
||||
public class TreeExpansionService {
|
||||
@@ -62,9 +62,9 @@ public class TreeExpansionService {
|
||||
}
|
||||
|
||||
public void load(List<String> treeExpansions) {
|
||||
List<TreePath> expandedPaths = new ArrayList<>();
|
||||
mainWindow.getBackgroundExecutor().execute(NLS.str("progress.load"),
|
||||
mainWindow.getBackgroundExecutor().execute(new LoadTask<>(
|
||||
() -> {
|
||||
List<TreePath> expandedPaths = new ArrayList<>();
|
||||
loadPaths(treeExpansions, expandedPaths);
|
||||
// send expand event to load sub-nodes and wait for completion
|
||||
UiUtils.uiRunAndWait(() -> expandedPaths.forEach(path -> {
|
||||
@@ -74,11 +74,12 @@ public class TreeExpansionService {
|
||||
throw new JadxRuntimeException("Tree expand error", e);
|
||||
}
|
||||
}));
|
||||
return expandedPaths;
|
||||
},
|
||||
s -> {
|
||||
expandedPaths -> {
|
||||
// expand paths after a loading task is finished
|
||||
expandedPaths.forEach(tree::expandPath);
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
private void loadPaths(List<String> treeExpansions, List<TreePath> expandedPaths) {
|
||||
|
||||
@@ -32,7 +32,6 @@ import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
@@ -377,8 +376,10 @@ public class MainWindow extends JFrame {
|
||||
if (!ensureProjectIsSaved()) {
|
||||
return;
|
||||
}
|
||||
closeAll();
|
||||
updateProject(new JadxProject(this));
|
||||
UiUtils.bgRun(() -> {
|
||||
closeAll();
|
||||
updateProject(new JadxProject(this));
|
||||
});
|
||||
}
|
||||
|
||||
private void saveProject() {
|
||||
@@ -540,6 +541,7 @@ public class MainWindow extends JFrame {
|
||||
synchronized (ReloadProject.EVENT) {
|
||||
saveAll();
|
||||
closeAll();
|
||||
System.gc();
|
||||
loadFiles(() -> {
|
||||
menuBar.reloadShortcuts();
|
||||
events().send(ReloadSettingsWindow.INSTANCE);
|
||||
@@ -571,25 +573,16 @@ public class MainWindow extends JFrame {
|
||||
onFinish.run();
|
||||
return;
|
||||
}
|
||||
AtomicReference<Exception> wrapperException = new AtomicReference<>();
|
||||
backgroundExecutor.execute(NLS.str("progress.load"),
|
||||
() -> {
|
||||
try {
|
||||
wrapper.open();
|
||||
} catch (Exception e) {
|
||||
wrapperException.set(e);
|
||||
LOG.error("Project load error", e);
|
||||
closeAll();
|
||||
}
|
||||
},
|
||||
status -> {
|
||||
if (wrapperException.get() != null) {
|
||||
closeAll();
|
||||
Exception e = wrapperException.get();
|
||||
if (e instanceof RuntimeException) {
|
||||
throw (RuntimeException) e;
|
||||
} else {
|
||||
throw new JadxRuntimeException("Project load error", e);
|
||||
}
|
||||
}
|
||||
if (status == TaskStatus.CANCEL_BY_MEMORY) {
|
||||
showHeapUsageBar();
|
||||
UiUtils.errorMessage(this, NLS.str("message.memoryLow"));
|
||||
@@ -600,8 +593,7 @@ public class MainWindow extends JFrame {
|
||||
return;
|
||||
}
|
||||
checkLoadedStatus();
|
||||
onOpen();
|
||||
onFinish.run();
|
||||
onOpen(onFinish);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -612,19 +604,21 @@ public class MainWindow extends JFrame {
|
||||
}
|
||||
|
||||
private void closeAll() {
|
||||
notifyLoadListeners(false);
|
||||
UiUtils.notUiThreadGuard();
|
||||
cancelBackgroundJobs();
|
||||
navController.reset();
|
||||
tabbedPane.reset();
|
||||
clearTree();
|
||||
resetCache();
|
||||
LogCollector.getInstance().reset();
|
||||
UiUtils.uiRunAndWait(() -> {
|
||||
tabsController.forceCloseAllTabs();
|
||||
tabbedPane.reset();
|
||||
navController.reset();
|
||||
shortcutsController.reset();
|
||||
clearTree();
|
||||
UiUtils.resetClipboardOwner();
|
||||
update();
|
||||
});
|
||||
wrapper.close();
|
||||
tabsController.forceCloseAllTabs();
|
||||
shortcutsController.reset();
|
||||
UiUtils.resetClipboardOwner();
|
||||
System.gc();
|
||||
UiUtils.uiRun(this::update);
|
||||
LogCollector.getInstance().reset();
|
||||
resetCache();
|
||||
notifyLoadListeners(false);
|
||||
}
|
||||
|
||||
private void checkLoadedStatus() {
|
||||
@@ -647,21 +641,23 @@ public class MainWindow extends JFrame {
|
||||
}
|
||||
}
|
||||
|
||||
private void onOpen() {
|
||||
private void onOpen(Runnable onFinish) {
|
||||
initTree();
|
||||
updateLiveReload(project.isEnableLiveReload());
|
||||
BreakpointManager.init(project.getFilePaths().get(0).toAbsolutePath().getParent());
|
||||
treeExpansionService.load(project.getTreeExpansions());
|
||||
List<EditorViewState> openTabs = project.getOpenTabs(this);
|
||||
backgroundExecutor.execute(NLS.str("progress.load"),
|
||||
backgroundExecutor.startLoading(
|
||||
() -> preLoadOpenTabs(openTabs),
|
||||
status -> {
|
||||
() -> {
|
||||
restoreOpenTabs(openTabs);
|
||||
runInitialBackgroundJobs();
|
||||
notifyLoadListeners(true);
|
||||
update();
|
||||
notifyLoadListeners(true);
|
||||
onFinish.run();
|
||||
checkIfCodeHasNonPrintableChars();
|
||||
runInitialBackgroundJobs();
|
||||
});
|
||||
// queue tree state restore after loading task
|
||||
treeExpansionService.load(project.getTreeExpansions());
|
||||
}
|
||||
|
||||
public void passesReloaded() {
|
||||
@@ -1592,18 +1588,26 @@ public class MainWindow extends JFrame {
|
||||
if (!ensureProjectIsSaved()) {
|
||||
return;
|
||||
}
|
||||
settings.setTreeWidth(treeSplitPane.getDividerLocation());
|
||||
settings.saveWindowPos(this);
|
||||
settings.setMainWindowExtendedState(getExtendedState());
|
||||
if (debuggerPanel != null) {
|
||||
saveSplittersInfo();
|
||||
}
|
||||
heapUsageBar.reset();
|
||||
closeAll();
|
||||
|
||||
editorThemeManager.unload();
|
||||
dispose();
|
||||
System.exit(0);
|
||||
UiUtils.bgRun(() -> {
|
||||
try {
|
||||
settings.setTreeWidth(treeSplitPane.getDividerLocation());
|
||||
settings.saveWindowPos(this);
|
||||
settings.setMainWindowExtendedState(getExtendedState());
|
||||
if (debuggerPanel != null) {
|
||||
saveSplittersInfo();
|
||||
}
|
||||
closeAll();
|
||||
UiUtils.uiRunAndWait(() -> {
|
||||
heapUsageBar.reset();
|
||||
editorThemeManager.unload();
|
||||
dispose();
|
||||
});
|
||||
} catch (Exception e) {
|
||||
LOG.error("Close window error", e);
|
||||
} finally {
|
||||
System.exit(0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void saveOpenTabs() {
|
||||
|
||||
Reference in New Issue
Block a user