0%

Android WebView 加载 html5 及 JS 交互框架

作者:Oz

当前越来越多的app中嵌入H5,想跟大家分享一下具体在项目中的使用和设计,故写了这个开源项目,欢迎大家批评指正。

在这里介绍一下OpenWeb项目基础的框架设计。

功能介绍

基于WebView设计的H5页面的加载框架,可以自动管理回退栈,可以支持js与native的交互,可配合下拉刷新控件,可修改横向进度条。

设计

核心类功能介绍

WebUrl.java

定义了String getCurrentUrl()接口,获取当前页面的的URL,用于记录当前页面的js回调注册。

BaseWebEvent.java

该类主要封装了基础的@JavascriptInterface接口,Handler消息常量定义及js的回调注册。

构造函数如下:

1
2
3
4
5
6
7
8

public BaseWebEvent(Context context, Handler handler, WebUrl url) {
this.mContext = context;
this.mHandler = handler;
this.mListener = new HashMap();
this.mUrlSource = url;
}

Handler消息封装如下,用于@JavascriptInterface接口发送消息处理:

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

/**
*
* @param what
* @param obj
*/
public void sendAsyncCallbackMessage(int what, Object obj) {
sendAsyncCallbackMessageDelay(what,obj,0);
}

/**
*
* @param what
* @param obj
* @param delay
*/
public void sendAsyncCallbackMessageDelay(int what, Object obj,long delay) {
if (mHandler != null) {
Message msg = mHandler.obtainMessage();
msg.what = what;
msg.obj = obj;
mHandler.sendMessageDelayed(msg,delay);
}
}

BaseWebFragment.java

这个类为抽象类是主要的WebView承载类,内部定义了WebView及BaseWebEvent及网络状态变化的监听等。

WebView的Settings配置,主要针对WebView做基础的设置,WebChromeClient,WebViewClient设置,以及对下载监听的设置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

protected void onInitWebViewSettings() {
//这里设置了基础的Settings
WebSettingsUtil.initSettings(this.mActivity, this.mWebView);
WebChromeClient webChromeClient = onCreateWebChromeClient();
if (webChromeClient != null) {
mWebView.setWebChromeClient(webChromeClient);
}
WebViewClient webViewClient = onCreateWebViewClient();
if (webViewClient != null) {
mWebView.setWebViewClient(webViewClient);
}
mWebView.setOverScrollMode(View.OVER_SCROLL_NEVER);
mWebView.requestFocus();
mWebView.setDownloadListener(new WebDownloadListener(this));
}

在子类的实现中应该覆写以下两个方法用于WebChromeClient,WebViewClient的设置:

1
2
3
4
5
6
7
8
9

protected WebChromeClient onCreateWebChromeClient() {
return new BaseWebChromeClient(this);
}

protected WebViewClient onCreateWebViewClient() {
return new BaseWebViewClient(this);
}

注意,要关注WebView可能存在内存泄露的问题,所以在Fragment的生命周期中针对WebView做相应操作,避免内存泄露问题

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

public void onResume() {
super.onResume();
if (mWebView != null) {
this.mWebView.onResume();
}
}

@Override
public void onPause() {
super.onPause();
if (mWebView != null) {
mWebView.onPause();
}
}

@Override
public void onDestroy() {
super.onDestroy();
if (mWebView != null) {
((ViewGroup) mWebView.getParent()).removeView(mWebView);
mWebView.destroy();
mWebView = null;
}
}

作为实现类必须实现以下两个函数,分别用于提供一个layout和一个下拉刷新的监听

1
2
3
4
5

protected abstract int loadLayoutRes();

protected abstract int getWebViewId();

OpenWebFragment.java

BaseWebFragment的子类,主要具体实现H5加载的业务逻辑。

其中,覆写onInitWebViewSettings方法,初始化mBaseEvent以及添加JavascriptInterface支持

1
2
3
4
5
6
7
8
9
10
11
12
13
14

@Override
protected void onInitWebViewSettings() {
super.onInitWebViewSettings();
this.mHandler = new WebFragmentHandler(this);
this.mWebEvent = new OpenWebEvent(this, this.mActivity, this.mHandler, new WebUrl() {
@Override
public String getCurrentUrl() {
return mWebView.getUrl();
}
});
this.mWebView.addJavascriptInterface(this.mWebEvent, "MyJsBridge");
}