一、WebView和H5交互接口(IEvent )定义
- H5和Android原生交互三要素:行为(方法)、参数、返回值。
- 定义一个通用的接口,包括上面三要素。
/**
* Web交互事件处理的接口定义
*/
public interface IEvent {
/**
* H5调用原生方法
* @param params 传递的是Json数据
* @return 也是Json数据
*/
String execute(String params);
}
注意:execute方法名称是和H5约定的。
- params:H5调用时传递过来的数据,用Json形式,比如H5要调用原生的分享,数据如下:
{
"action": "share",// 行为:分享
// 分享要使用到的数据
"data": {
"shareTitle": "",
"shareDes": "",
"shareImageUrl": "",
"shareActionUrl": "",
"shareType": "",
....// 其它参数
}
}
- 返回String类型也是用Json,比如H5要获取原生的UserToken数据如下:
// params:H5调用时传递过来的数据
{
"action": "getUserToken",// 行为:获取用户的UserToken
// 无数据传递给Android
"data": {
}
}
// Android返回给H5的数据
{
"action": "getUserToken",// 行为:获取用户的UserToken
// Android给H5的数据
"data": {
"userToken":"xxxxxx"
}
}
二、WebView和H5交互方法参数和返回值的定义
- 数据和返回值无论是数据格式还是形式,其实都是一样。
- Android解析H5传递过来的参数时候,可以根据Action的值去解析Data的值。
- Data的值是不确定的,不确定的可以用泛型定义。
/**
* 1. H5传递过来的参数
*/
public class ParamsData<T> {
public String action;
public T data;
}
/**
* 2. 返回给H5的参数
*/
public class ReturnParamsData<T> {
public String action;
public T data;
public ReturnParamsData(String action) {
this.action = action;
}
}
三、WebView和H5交互接口(IEvent )实现
/**
* Web JS交互的事件处理
*/
public class JSEvent implements IEvent {
private Activity activity;
public JSEvent(Activity activity) {
this.activity = activity;
}
@Override
@JavascriptInterface
public String execute(String params) {
// TODO 待解析params数据
return null;
}
}
注意:execute方法上要加上@JavascriptInterface
四、数据解析和返回给H5的数据创建(用到JSONObject和Gson)
/**
* Web JS交互的事件处理
*/
public class JSEvent implements IEvent {
// 实际开发用得上
private Activity mActivity;
private Gson gson = new Gson();
public JSEvent(Activity activity) {
this.mActivity = activity;
}
@Override
@JavascriptInterface
public String execute(String params) {
// 1. 先判断数据是不是空
if (!TextUtils.isEmpty(params)) {
try {
JSONObject object = new JSONObject(params);
// 2. 拿到行为
String action = object.getString("action");
// 3. 创建返回的数据
ReturnParamsData rData = new ReturnParamsData(action);
// 4. 根据行为去做真正的数据解析
switch (action) {
case "share": // 分享行为
// 分享数据解析
ShareData shareData = parseJson(ShareData.class, params);
// TODO 调原生要做的事情
break;
}
// 5. 组装H5要的数据
rData.data=getReturnData(action);
// 返回给H5的数据,自己组装好
return gson.toJson(rData);
} catch (Throwable e) {
e.printStackTrace();
}
}
return null;
}
/**
* 根据动作,组装数据给H5
*/
private ReturnData getReturnData(String action) {
ReturnData rData = new ReturnData();
switch (action){
case "getUserToken":
rData.userToken="用户的UserToken";
break;
case "getUserId":
rData.userId="用户的UserId";
break;
}
return rData;
}
/**
* 解析H5传递过来的数据
*
* @param clazz T的实际类型
* @param json H5传递过来的参数
* @param <T> 实际类型
* @return 实际类型
*/
private <T> T parseJson(Class<?> clazz, String json) {
Type type = new ParamsTypeImpl(ParamsData.class, new Type[]{clazz});
ParamsData<T> data = gson.fromJson(json, type);
return data.data;
}
}
// -----------------------------------下面是用到的类,实际开发根据项目定义---------------------------------------
/**
* 分享的数据的实体Bean
*/
public class ShareData {
public String shareTitle;
public String shareDes;
public String shareImageUrl;
public String shareActionUrl;
public String shareType;
}
/**
* H5要的数据,根据实际项目,可以继续扩展
*/
public class ReturnData {
public String userToken; // 用户的Token
public String userId;// 用户ID
public String userType;// 用户类型
}
/**
* 解析JavaBean的实际类型
*/
public class ParamsTypeImpl implements ParameterizedType {
private final Class raw;
private final Type[] args;
public ParamsTypeImpl(Class raw, Type[] args) {
this.raw = raw;
this.args = args != null ? args : new Type[0];
}
@Override
public Type[] getActualTypeArguments() {
return args;
}
@Override
public Type getRawType() {
return raw;
}
@Override
public Type getOwnerType() {
return null;
}
}
四、项目里面使用
/**
* JS注入的名称,和H5约定的
*/
private static final String JS_NAME = "appXXX";
@SuppressLint("JavascriptInterface")
private void initWebView() {
// ...... 前面省去一些代码
WebSettings webSetting = webView.getSettings();
// ===设置JS可用
webSetting.setJavaScriptEnabled(true);
// JS打开窗口
webSetting.setJavaScriptCanOpenWindowsAutomatically(true);
// ===设置JS可用
// 注入JS交互
mWebView.addJavascriptInterface(new JSEvent(this), JS_NAME);
}
至此WebView的使用写完。