diff --git a/app/src/main/java/com/itsaky/androidide/fragments/output/BuildOutputFragment.kt b/app/src/main/java/com/itsaky/androidide/fragments/output/BuildOutputFragment.kt index 98116433f8..f12311e0e0 100644 --- a/app/src/main/java/com/itsaky/androidide/fragments/output/BuildOutputFragment.kt +++ b/app/src/main/java/com/itsaky/androidide/fragments/output/BuildOutputFragment.kt @@ -91,7 +91,12 @@ class BuildOutputFragment : NonEditableEditorFragment() { } override fun clearOutput() { - buildOutputViewModel.clear() + // This fragment uses `activityViewModels()`, which relies on the fragment being attached. + // `clearOutput()` can be triggered from build/service callbacks even after the fragment + // has been detached, so we must guard before touching the activity-scoped ViewModel. + if (isAdded && !isDetached) { + buildOutputViewModel.clear() + } super.clearOutput() } diff --git a/app/src/main/java/com/itsaky/androidide/fragments/output/ShareableOutputFragment.kt b/app/src/main/java/com/itsaky/androidide/fragments/output/ShareableOutputFragment.kt index fd12a850b4..45de634d35 100644 --- a/app/src/main/java/com/itsaky/androidide/fragments/output/ShareableOutputFragment.kt +++ b/app/src/main/java/com/itsaky/androidide/fragments/output/ShareableOutputFragment.kt @@ -29,6 +29,12 @@ interface ShareableOutputFragment { /** Get the name of the file to which the output will be written. */ fun getShareableFilename(): String - /** Clear the output of this fragment. */ + /** + * Clear the output of this fragment. + * + * Note: Callers may invoke this while the fragment is detached (for example, from a + * build/service callback). Implementations that use activity-scoped ViewModels must + * guard against `!isAdded || isDetached` before touching them. + */ fun clearOutput() } diff --git a/app/src/main/java/com/itsaky/androidide/ui/EditorBottomSheet.kt b/app/src/main/java/com/itsaky/androidide/ui/EditorBottomSheet.kt index f912b5b68a..4c2610b058 100644 --- a/app/src/main/java/com/itsaky/androidide/ui/EditorBottomSheet.kt +++ b/app/src/main/java/com/itsaky/androidide/ui/EditorBottomSheet.kt @@ -430,7 +430,16 @@ constructor( suppressedGradleWarnings.any { msg.contains(it) } fun clearBuildOutput() { - pagerAdapter.buildOutputFragment?.clearOutput() + // Always clear the persistent build output state via the bottom sheet's + // activity-scoped ViewModel. + buildOutputViewModel.clear() + + // `clearOutput()` on the fragment may touch additional UI state, so only call it when + // the fragment is currently attached to an activity. + val fragment = pagerAdapter.buildOutputFragment + if (fragment != null && fragment.isAdded && !fragment.isDetached) { + fragment.clearOutput() + } } fun handleDiagnosticsResultVisibility(errorVisible: Boolean) {