-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathSafeWebView.java
More file actions
111 lines (91 loc) · 2.91 KB
/
SafeWebView.java
File metadata and controls
111 lines (91 loc) · 2.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/**
* 解决一些低版本安全和内存泄露问题的WebView<br/>
*
* @author Created by maxwell-nc on 2016-09-09
*/
public class SafeWebView extends WebView {
/**
* 添加的JS接口列表
*/
private List<String> mJsInterfaceNames;
public SafeWebView(Context context) {
super(context);
}
public SafeWebView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SafeWebView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
/**
* 此方法安全移除{@link Build.VERSION_CODES#JELLY_BEAN_MR1}版本下可能导致访问用户本地文件的安全性bug
*/
@SuppressLint({"JavascriptInterface", "AddJavascriptInterface"})
public void addJsInterface(Object object, String name) {
super.addJavascriptInterface(object, name);
//移除低版本默认添加的Js接口(可能存在安全隐患)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
removeJavascriptInterface("searchBoxJavaBridge_");
removeJavascriptInterface("accessibility");
removeJavascriptInterface("accessibilityTraversal");
}
//记录js接口名称,用于释放
if (mJsInterfaceNames == null) {
mJsInterfaceNames = new ArrayList<>();
}
mJsInterfaceNames.add(name);
}
/**
* 移除所有已经添加的JS接口
*/
public void removeAllJavascriptInterface() {
for (String name : mJsInterfaceNames) {
super.removeJavascriptInterface(name);
}
}
/**
* 防止内存泄露<br/>
* 请接着调用:<b>webView = null;</b>
*/
public void release() {
setVisibility(View.GONE);
//WebView依附移除
ViewGroup parent = (ViewGroup) getParent();
parent.removeView(this);
//移除放大缩小按钮等view
removeAllViews();
//移除JS接口
removeAllJavascriptInterface();
super.destroy();
}
/**
* 加载HTML文本
*
* @param html html内容
*/
public void loadHtml(String html) {
if (TextUtils.isEmpty(html)) {
return;
}
loadDataWithBaseURL(null, html, "text/html", "utf-8", null);
invalidate();
}
/**
* 开启加载JavaScript
*/
@SuppressLint("SetJavaScriptEnabled")
public void withJs() {
getSettings().setJavaScriptEnabled(true);
}
/**
* 禁止访问本地文件的WebViewClient<br/>
* 防止安全性问题
*/
public static class NoLocalReadWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//禁止访问本地文件
return !url.startsWith("file://") || super.shouldOverrideUrlLoading(view, url);
}
}
}