Skip to content

Commit

Permalink
Improve the workaround by using bundle
Browse files Browse the repository at this point in the history
  • Loading branch information
louischan-oursky committed Oct 25, 2024
1 parent d92dd00 commit 00dc463
Showing 1 changed file with 22 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,16 @@ internal class LatteFragment() : Fragment() {
get() = mutWebView!!
set(value) { mutWebView = value }

// This flag is used to work around an issue of fragment re-creation.
// This is a workaround for the an issue of fragment re-creation observed with androidx.navigation.
// When this fragment is used with androidx.navigation,
// this fragment may be onDestroyView(), and then onCreateView() again.
// If that happens, the webView may never has its load() called.
// However, even with this fix, savedInstanceState was never called, so
// the webView will show the initial screen.
private var waitWebViewToLoadIsCalledInThisLifecycle: Boolean = false
// this fragment may be onDestroyView(), and then onCreateView() again, without
// onSaveInstanceState() being called at all.
// It is also observed that the same instance of fragment is used when this happens.
// Therefore, here are the preconditions of this workaround.
// 1. onDestroyView() is called, and onSaveInstanceState() IS NOT called.
// 2. The fragment itself is NOT discarded and re-instantiated again, so storing things
// in class properties work well in case of this workaround.
private var androidxNavigationWorkaroundBundle: Bundle? = null

private var webViewOnReady: (() -> Unit)? = null
private var webViewOnComplete: ((result: Result<WebViewResult>) -> Unit)? = null
Expand Down Expand Up @@ -198,7 +201,6 @@ internal class LatteFragment() : Fragment() {
}
this@LatteFragment.webViewOnReady = webViewOnReady
this@LatteFragment.webViewOnComplete = webViewOnComplete
this@LatteFragment.waitWebViewToLoadIsCalledInThisLifecycle = true
webView.load()
}
}
Expand Down Expand Up @@ -321,16 +323,16 @@ internal class LatteFragment() : Fragment() {
savedInstanceState: Bundle?
): View {
Log.d(TAG, "onCreateView $this")
val webViewStateBundle = savedInstanceState?.getBundle(KEY_WEBVIEW_STATE)
val ctx = requireContext()
constructWebViewIfNeeded(ctx, webViewStateBundle)

// This lifecycle started.
// If waitWebViewToLoad is called, then waitWebViewToLoadIsCalledInThisLifecycle is true.
// if waitWebViewToLoadIsCalledInThisLifecycle is true, then webView.load() was called there.
// Otherwise, we have to call webView.load() here.
if (!waitWebViewToLoadIsCalledInThisLifecycle) {
webView.load()
val webViewStateBundle = savedInstanceState?.getBundle(KEY_WEBVIEW_STATE)
if (webViewStateBundle != null) {
Log.d(TAG, "onCreateView restore state from standard bundle $this")
constructWebViewIfNeeded(ctx, webViewStateBundle)
} else if (this.androidxNavigationWorkaroundBundle != null) {
Log.d(TAG, "onCreateView restore state from workaround bundle $this")
constructWebViewIfNeeded(ctx, this.androidxNavigationWorkaroundBundle)
this.androidxNavigationWorkaroundBundle = null
}

val intentFilter = IntentFilter(Latte.BroadcastType.RESET_PASSWORD_COMPLETED.action)
Expand All @@ -349,9 +351,10 @@ internal class LatteFragment() : Fragment() {
Log.d(TAG, "onDestroyView $this")
super.onDestroyView()

// This lifecycle ended.
// Reset waitWebViewToLoadIsCalledInThisLifecycle to false.
waitWebViewToLoadIsCalledInThisLifecycle = false
Log.d(TAG, "onDestroyView save state to workaround bundle $this")
val webViewState = Bundle()
webView.saveState(webViewState)
this.androidxNavigationWorkaroundBundle = webViewState

removeWebViewFromParent(webView)
mutWebView = null
Expand All @@ -363,6 +366,7 @@ internal class LatteFragment() : Fragment() {
Log.d(TAG, "onSaveInstanceState $this")
super.onSaveInstanceState(outState)
val webView = mutWebView ?: return
Log.d(TAG, "onDestroyView save state to standard bundle $this")
val webViewState = Bundle()
webView.saveState(webViewState)
outState.putBundle(KEY_WEBVIEW_STATE, webViewState)
Expand Down

0 comments on commit 00dc463

Please sign in to comment.