Android WebView关于内存泄漏疑问及启动卡顿问题
大嘎好,今天我记录对于我来说项目中经常会遇到的关于WebView的问题。
猴赛雷
第一先说一下WebView内存泄漏的问题,网上收了很多资料,至于内存泄漏的原因大致就是WebView会因为一些原因持有Activity里面的引用,并且WebView并不会随着Activity销毁而销毁导致此Activity无法被回收。
处理的方法大致分两种
一种是通过动态添加WebView的方式替代直接写在XML里面,并且上下文对象传入Application。然后在Activity销毁时处理一下WebView.代码如下
webView = WebView(App.getIns())
val params = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT
)
webView?.layoutParams=params
webContainer.addView(webView)
webView?.loadUrl("https://www.jianshu.com/p/8311410de676")
override fun onDestroy() {
val group = webView?.parent as ViewGroup
group?.removeView(webView)
webView?.stopLoading()
webView?.getSettings()?.setJavaScriptEnabled(false);
webView?.clearHistory();
webView?.clearView();
webView?.removeAllViews();
webView?.destroy();
super.onDestroy()
}
第二种方式是通过给含有WebView的Activity配置新进程,并在这个Activity销毁的时候调用
System.exit(0)
来强制关闭这个进程,这个方法可以说是非常暴力非常直接。
下面说一下遇到的第二个问题, 在startActivity到含有WebView的Activity时,第一次跳转会有明显的卡顿。手机性能越差这个卡顿越明显。
一想到卡顿第一反应就是主线程做了耗时操作,于是我机智的想开个子线程去创建WebView然后在主线程中再去AddView添加到视图上。。。。然后我就这么操作了
结果报了这么一个错
java.lang.RuntimeException: WebView cannot be initialized on a thread that has no Looper.
好吧。子线程中肯定行不通的,然后我又机智的想到能不能等跳转Activity完成之后再加载WebView.
那么把添加WebView的时机放到onWindowFocusChanged
中
override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
if (hasFocus&&isFirst){
webView = WebView(App.getIns())
val params = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT
)
webView?.layoutParams=params
webContainer.addView(webView)
webView?.loadUrl("https://www.jianshu.com/p/8311410de676")
}
}
然后测试了一下有效果了,但是效果只能说一般,跳转速度大概快了一半。考虑了一下可能还是因为onWindowFocusChanged
不够靠后,那么干脆一点 我们直接做一个200毫秒的延迟试一试
Observable.interval(200,TimeUnit.MILLISECONDS)
.take(1)
.observeOn(AndroidSchedulers.mainThread())
.doOnComplete {
initWebView()
}
.subscribe()
测了一下,效果很棒,Activity是打到了瞬开,至于WebView的加载时机反正本菜鸡这里设置的是200毫秒,我能接受这个延迟,大家也可以自己再减一点测试一下。