一雀瓢、WebView 常見的一些坑
1. webview 在android api16以及之前版本的安全漏洞垛玻,該漏洞是因為程序沒有正確的限制webview.addjavascriptinterface方法桂对,讓遠(yuǎn)程攻擊者可以使用java的反射機(jī)制利用該漏洞執(zhí)行任意的java對象方法。
2. webview動態(tài)添加到其他布局的時候,在activity銷毀的生命周期時甩挫,需要主動調(diào)用webview.removeallviews和webview的ondestory方法釋放內(nèi)存,否則會導(dǎo)致內(nèi)存泄漏炮障。
3. jsbridge 目派,js橋可以允許遠(yuǎn)程網(wǎng)頁端與android的native端進(jìn)行通信,通俗的說就是使用js橋可以在android代碼中調(diào)用網(wǎng)頁的js方法胁赢,也可以讓js調(diào)用原生的代碼
4. webview.onpagefinished方法企蹭,該方法并不靠譜,按照api上面的說法智末,在web頁面完全加載完成的時候會回調(diào)該方法谅摄,但在實際應(yīng)用過程中,該方法在跳轉(zhuǎn)url的時候會被多次調(diào)用系馆,更加靠譜的方法是使用onprogresschange方法代替該方法的功能螟凭,當(dāng)newProgress為100的時候,即是頁面加載完成它呀。
5. 后臺耗電問題螺男,webview加載網(wǎng)頁的時候,會自動創(chuàng)建線程纵穿,如果如果使用不當(dāng)下隧,這些線程會永遠(yuǎn)在后臺運行,導(dǎo)致你的應(yīng)用耗電量居高不下谓媒,這個問題的解決方式是在activity的ondetory方法中銷毀webview淆院。
6. webview硬件加速導(dǎo)致渲染問題,比如加載的時候會有閃屏現(xiàn)象句惯,解決方式就是暫時關(guān)閉硬件加速土辩。
7. webview導(dǎo)致內(nèi)存溢出的原因,主要是因為內(nèi)部類持有外部類的引用導(dǎo)致外部類無法釋放的問題抢野。
二拷淘、關(guān)于webView的內(nèi)存泄漏問題
1、不要在.xml文件中定義webview節(jié)點
2指孤、 從根源解決(劃重點)
前面的方法都沒有解決我內(nèi)存泄漏的問題启涯,然后我看到了一篇文章是從源碼角度分析了webview內(nèi)存泄漏的原因,最后按作者的方法解決了問題恃轩,后面會貼上原文地址结洼。這里簡單說一下:
原文里說的webview引起的內(nèi)存泄漏主要是因為org.chromium.android_webview.AwContents 類中注冊了component callbacks,但是未正常反注冊而導(dǎo)致的叉跛。
org.chromium.android_webview.AwContents 類中有這兩個方法 onAttachedToWindow 和 onDetachedFromWindow松忍;系統(tǒng)會在attach和detach處進(jìn)行注冊和反注冊component callback;
在onDetachedFromWindow() 方法的第一行中:
if (isDestroyed()) return;筷厘,
如果 isDestroyed() 返回 true 的話鸣峭,那么后續(xù)的邏輯就不能正常走到伟桅,所以就不會執(zhí)行unregister的操作;我們的activity退出的時候叽掘,都會主動調(diào)用 WebView.destroy() 方法楣铁,這會導(dǎo)致 isDestroyed() 返回 true;destroy()的執(zhí)行時間又在onDetachedFromWindow之前更扁,所以就會導(dǎo)致不能正常進(jìn)行unregister()盖腕。
然后解決方法就是:讓onDetachedFromWindow先走,在主動調(diào)用destroy()之前浓镜,把webview從它的parent上面移除掉溃列。
ViewParent parent = mWebView.getParent();
if (parent != null) {
((ViewGroup) parent).removeView(mWebView);
}
mWebView.destroy();
完整的activity的onDestroy()方法:
@Override
protected void onDestroy() {
if( mWebView!=null) {
// 如果先調(diào)用destroy()方法,則會命中if (isDestroyed()) return;這一行代碼膛薛,需要先onDetachedFromWindow()听隐,再
// destory()
ViewParent parent = mWebView.getParent();
if (parent != null) {
((ViewGroup) parent).removeView(mWebView);
}
mWebView.stopLoading();
// 退出時調(diào)用此方法,移除綁定的服務(wù)哄啄,否則某些特定系統(tǒng)會報錯
mWebView.getSettings().setJavaScriptEnabled(false);
mWebView.clearHistory();
mWebView.clearView();
mWebView.removeAllViews();
mWebView.destroy();
}
super.on Destroy();
}
這個方法親測有效雅任。
作者:wencymu
鏈接:http://www.reibang.com/p/3e8f7dbb0dc7
來源:簡書
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán)咨跌,非商業(yè)轉(zhuǎn)載請注明出處沪么。