如何在jetpack compose上回收webview?
Posted
技术标签:
【中文标题】如何在jetpack compose上回收webview?【英文标题】:How to recycle a webview on jetpack compose? 【发布时间】:2022-01-07 07:03:01 【问题描述】:我有一个通过HorizontalPager
模拟ViewPager
行为的应用程序。每个寻呼机都有一个WebView
,ViewPager
会为远离当前页面的页面释放WebView
。我应该在 Jetpack Compose 中做什么?看来组合组件不应该被销毁
【问题讨论】:
【参考方案1】:这是预期的行为。 ViewPager
是一个惰性视图,它不会存储不可见的视图。
在明确的 Compose 中,您需要缓存的只是滚动位置和其他一些状态变量,而 Compose 会这样做。
但是当您使用androidView
时,您必须自己管理它。我不确定是否可以检索 WebView
滚动位置,但即使可以 - 页面仍然会重新加载。
一种可能的解决方案是将WebViews
存储为如下状态:
val webViews = remember(LocalContext.current) mutableStateMapOf<Int, WebView>()
val state = rememberPagerState()
LaunchedEffect(state.currentPage)
webViews.keys.forEach key ->
val maxCacheDistance = 3
if (abs(key - state.currentPage) >= maxCacheDistance)
webViews.remove(key)
println("webView $key deinited")
HorizontalPager(
count = 10,
state = state,
) page ->
val url = "https://duckduckgo.com/?q=$page"
AndroidView(
factory = context ->
webViews[page] ?: run
WebView(context).also webView ->
webView.settings.javascriptEnabled = true
webViews[page] = webView
,
update = webView ->
if (webView.url != url)
webView.loadUrl(url)
,
modifier = Modifier.fillMaxSize()
)
【讨论】:
我认为如果WebView的Composable没有被调用,WebView应该被回收,所以也许我可以添加一个判断是否调用composable的条件 @Kennir “未调用 WebView”是什么意思?我只在它第一次出现时创建它 嗨@philip-dukhov,我的意思是不要调用包含WebView的可组合函数如果当前索引足够远,例如: if (abs(pageIndex, currentIndex) @KennirHorizontalPager
工作很懒,它不会调用所有页面的内容。在初始加载时,它只会加载第一个和第二个项目。
很抱歉我没有解释清楚,比如我想销毁第一页的webview释放内存,如果当前页面移动到3或更大,然后重新创建如果当前页面移回 2 或小则为 webview【参考方案2】:
您应该向实现 WebView 的类添加一个函数,该函数调用 onDestroy 并将当前页面替换为空白页面。用空白页面替换当前网页将终止任何 javascript。例如,在我的应用中,我使用 WebView 来播放 YouTube 视频:
class VideoPlayerView() : WebView(ctx)
fun terminateWebView()
// Reload the webview with a blank page. This is needed to kill any video playing.
loadData("<html><body></body></html>", "text/html", "base64")
this.destroy()
当您导航回上一个屏幕时,您应该调用您的终止函数。是否要在滑动标签时清除 web 视图是您必须做出的决定。在我的应用程序中,因为我在一个选项卡中播放视频,所以当用户滑动到另一个选项卡时,我需要终止视频。但是如果您的应用没有播放视频等媒体内容,那么您可能不需要终止 webview。
【讨论】:
以上是关于如何在jetpack compose上回收webview?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Jetpack Compose UI 在 Android 上正确跟踪屏幕视图?