flutter_inappwebview icon indicating copy to clipboard operation
flutter_inappwebview copied to clipboard

InAppWebViewManager: fix nullptr in InAppWebViewManager.dispose

Open Murmurl912 opened this issue 1 year ago • 2 comments

Connection with issue(s)

Resolve issue #2025

Connected to #2025

Testing and Review Notes

Use the demo project to test if this works: https://github.com/Murmurl912/inappwebview_dispose_keepalive_nullptr

Screenshots or Videos

To Do

  • [ ] double check the original issue to confirm it is fully satisfied
  • [ ] add testing notes and screenshots in PR description to help guide reviewers
  • [x] request the "UX" team perform a design review (if/when applicable)

Murmurl912 avatar Feb 20 '24 03:02 Murmurl912

I've tested this locally and it fixes the Android null pointer exception when disposing webview that is using keep alive

HammadBukhari avatar Feb 27 '24 11:02 HammadBukhari

Seems like we can expect an update soon, no need to jump package #2268

malthee avatar Sep 22 '24 15:09 malthee

Fixed in https://github.com/pichillilorenzo/flutter_inappwebview/commit/4ba6e22848aae9c2ca16bc784023b7fa98cf61e3

Thanks

pichillilorenzo avatar Oct 25 '24 14:10 pichillilorenzo

@all-contributors please add @Murmurl912 for code

pichillilorenzo avatar Oct 25 '24 14:10 pichillilorenzo

@pichillilorenzo

I've put up a pull request to add @Murmurl912! :tada:

allcontributors[bot] avatar Oct 25 '24 14:10 allcontributors[bot]

Before the next release resolves this issue. Anyone using keepAlive should use the following code to safely dispose the InAppWebViewFlutterPlugin. Simply using a try-catch block will prevent the Flutter engine from completely destroy, which can lead to memory leaks and other issues.

It took me several weeks of investigation to discover that a SqliteException(5): while executing statement, database is locked error was actually caused by the Flutter engine not being disposed of properly.

override fun onDestroy() {
    try {
        super.onDestroy()
    } catch (e: Exception) {
        // no-op
    }
}

Instead, using to following code the remove null webview from inAppWebViewManager :

import com.pichillilorenzo.flutter_inappwebview_android.InAppWebViewFlutterPlugin


override fun onDestroy() {
    safeDispose()
    super.onDestroy()
}


private fun safeDispose() {
    kotlin.runCatching {
        val flutterEngine = flutterEngine ?: return
        val plugins = flutterEngine.plugins.get(InAppWebViewFlutterPlugin::class.java) as? InAppWebViewFlutterPlugin
            ?: return
        val manager = plugins.inAppWebViewManager ?: return
        val clone = manager.keepAliveWebViews.toMap()
        for (entry in clone) {
            if (entry.value == null) {
                manager.keepAliveWebViews.remove(entry.key)
            }
        }
    }
}

Murmurl912 avatar Nov 04 '24 04:11 Murmurl912