Android WebView关于内存泄漏疑问及启动卡顿问题

2019-12-04  本文已影响0人  宇智波_佐星

大嘎好,今天我记录对于我来说项目中经常会遇到的关于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毫秒,我能接受这个延迟,大家也可以自己再减一点测试一下。

上一篇 下一篇

猜你喜欢

热点阅读