Android开发经验谈:webview内存泄漏

作者: 飞鱼_9d08 | 来源:发表于2020-05-28 17:55 被阅读0次

    看了很多WebView内存泄漏的博文,很多文章都有多多少少的问题。

    我便在我这篇博文中仔细针对webView内存泄漏进行分析。

    看这篇文章的人都应该对webview深恶痛绝

    怎么总是释放不掉呢???

    释放不掉的原因是啥呢???

    为啥特么的总是阴魂不散呢???

    答:webView内部的一些线程持有activity对象,导致activity无法释放。继而内存泄漏。

    解决:

    方案一:退出程序调用

    System.exit(0);
    

    弊:太暴力,只能在程序退出后清除持有。

    方案二:activity弱应用持有

    private WeakReference<BaseWebActivity> webActivityReference = new WeakReference<BaseWebActivity>(this);
    bridgeWebView = new BridgeWebView(webActivityReference .get());
    bridgeWebView.setLayoutParams(params);
    container.addView(bridgeWebView);
    
    在销毁中执行
     @Override
        protected void onDestroy() {
            super.onDestroy();
            //防止webView内存泄漏
            if (bridgeWebView != null) {
                //先从父容器中移除webview,然后再销毁webview
                ViewParent parent = bridgeWebView.getParent();
                if (parent != null) {
                    ((ViewGroup) parent).removeView(bridgeWebView);
                }
                bridgeWebView.stopLoading();
                // 退出时调用此方法,移除绑定的服务,否则某些特定系统会报错
                bridgeWebView.getSettings().setJavaScriptEnabled(false);
                bridgeWebView.clearHistory();
                bridgeWebView.clearView();
                bridgeWebView.removeAllViews();
                try {
                    bridgeWebView.destroy();
                } catch (Throwable ex) {
    
                }
                bridgeWebView = null;
                this.webActivityReference.clear();
                this.webActivityReference = null;
            }
        }
    

    说明:

    看了很多文章,文中大多都建议不在xml中写webview,都没有说明原因。主要是xml中创建的webview持有Activity的context对象

    方案三:新建进程

    缺点:新建进程比较麻烦的在于进程间通讯

    还存在如下问题

    • 静态成员和单例模式失效

    • 线程同步机制失效

    • SharedPreferences 可靠性降低

    • Application 被多次创建

    优点:

    增加应用可用的内存空间,不与主进程竞争内存空间,不使用进程则销毁。

    通讯方式

    • AIDL:功能强大,支持进程间一对多的实时并发通信,并可实现 RPC (远程过程调用)。

    • Messenger:支持一对多的串行实时通信, AIDL 的简化版本。

    • Bundle:四大组件的进程通信方式,只能传输 Bundle 支持的数据类型。

    • ContentProvider:强大的数据源访问支持,主要支持 CRUD 操作,一对多的进程间数据共享,例如我们的应用访问系统的通讯录数据。

    • BroadcastReceiver:即广播,但只能单向通信,接收者只能被动的接收消息。

    • 文件共享:在非高并发情况下共享简单的数据。

    • Socket:通过网络传输数据。

    实例:

    //xml配置activity,在remoteweb进程中
    <activity android:name=".WebActivity"
       android:process=":remoteweb"/>
    
    

    相关文章

      网友评论

        本文标题:Android开发经验谈:webview内存泄漏

        本文链接:https://www.haomeiwen.com/subject/ibiaahtx.html