From 36cf6d6d5ec13eda98a09d4f3a69722e4dbd89e7 Mon Sep 17 00:00:00 2001 From: Akash Yadav Date: Fri, 10 Mar 2023 16:31:59 +0530 Subject: [PATCH] fix: ToolingServerListener is not released properly, resulting in memory leak --- .../activities/editor/ProjectHandlerActivity.kt | 10 +++++++++- .../services/builder/GradleBuildService.java | 8 +++++++- .../androidide/services/builder/ToolingServerRunner.kt | 8 ++++++-- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/itsaky/androidide/activities/editor/ProjectHandlerActivity.kt b/app/src/main/java/com/itsaky/androidide/activities/editor/ProjectHandlerActivity.kt index 65becd43b..0fa56a59b 100644 --- a/app/src/main/java/com/itsaky/androidide/activities/editor/ProjectHandlerActivity.kt +++ b/app/src/main/java/com/itsaky/androidide/activities/editor/ProjectHandlerActivity.kt @@ -135,7 +135,7 @@ abstract class ProjectHandlerActivity : BaseEditorActivity(), IProjectHandler { override fun preDestroy() { if (isDestroying) { - + releaseServerListener() this.initializingFuture?.cancel(true) this.initializingFuture = null @@ -254,6 +254,8 @@ abstract class ProjectHandlerActivity : BaseEditorActivity(), IProjectHandler { } this.initializingFuture!!.whenCompleteAsync { result, error -> + releaseServerListener() + if (result == null || error != null) { log.error("An error occurred initializing the project with Tooling API", error) setStatus(getString(string.msg_project_initialization_failed)) @@ -264,6 +266,12 @@ abstract class ProjectHandlerActivity : BaseEditorActivity(), IProjectHandler { } } + private fun releaseServerListener() { + // Release reference to server listener in order to prevent memory leak + (Lookup.DEFAULT.lookup(BuildService.KEY_BUILD_SERVICE) as? GradleBuildService?) + ?.setServerListener(null) + } + override fun stopLanguageServers() { try { destroyLanguageServers(isChangingConfigurations) diff --git a/app/src/main/java/com/itsaky/androidide/services/builder/GradleBuildService.java b/app/src/main/java/com/itsaky/androidide/services/builder/GradleBuildService.java index 328892565..4e96a4a71 100644 --- a/app/src/main/java/com/itsaky/androidide/services/builder/GradleBuildService.java +++ b/app/src/main/java/com/itsaky/androidide/services/builder/GradleBuildService.java @@ -343,6 +343,12 @@ public class GradleBuildService extends Service implements BuildService, IToolin return gradlew.exists() && gradleWrapperJar.exists() && gradleWrapperProps.exists(); } + public void setServerListener (@Nullable ToolingServerRunner.OnServerStartListener listener) { + if (this.toolingServerThread != null) { + this.toolingServerThread.setListener(listener); + } + } + private CompletableFuture installWrapper() { if (eventListener != null) { eventListener.onOutput("-------------------- NOTE --------------------"); @@ -478,7 +484,7 @@ public class GradleBuildService extends Service implements BuildService, IToolin if (toolingServerThread.isStarted() && listener != null) { listener.onServerStarted(); } else { - toolingServerThread.setListener(listener); + setServerListener(listener); } } diff --git a/app/src/main/java/com/itsaky/androidide/services/builder/ToolingServerRunner.kt b/app/src/main/java/com/itsaky/androidide/services/builder/ToolingServerRunner.kt index 3c1f008da..8c247eeef 100644 --- a/app/src/main/java/com/itsaky/androidide/services/builder/ToolingServerRunner.kt +++ b/app/src/main/java/com/itsaky/androidide/services/builder/ToolingServerRunner.kt @@ -123,8 +123,12 @@ internal class ToolingServerRunner( override fun interrupt() { super.interrupt() - listener = null - observer = null + release() + } + + internal fun release() { + this.listener = null + this.observer = null } interface Observer {