现在的移动端开发中,越来越多的开发人员在使用混合式开发的模式;加载方便,布局简单,不占用手机内存等等优点使得混合式开发的项目让越来越多的人喜欢,现在我就给大家介绍两种不同的纯Android和H5界面之间的交互方式,由于技术浅薄,很多地方可能存在缺漏,欢迎大家批评指正!
第一种方式很简单,只要简单的进行加载H5界面就可以,这种加载方式比较适合初学者使用,因为大部分的数据渲染的工作可能会放在h5界面中进行,但是同样也存在界面稳定性不是很高的现象,下面我们来看下这个代码:
Intent i = new Intent();
i.setClass(context, WebActivity.class);
AppInfoHelper.clearParamForWebPage();
AppInfoHelper.setParamForWebPage(2, data.getResourceId());
i.putExtra("url", Const.H5URL.URL_LOAN_APPLY_DETAIL);
context.startActivity(i);
上面的逻辑中其实就是一个很简单的页面跳转逻辑,其中的WebActiity是用来加载所有的h5界面的一个通用类,所有的h5加载方法均调用这个类对h5的界面进行加载,data是上一个页面中获取到的数据,或者本页面中访问网络获取到的数据,把对应的想传递的通过上面的形式塞到h5界面中,AppInfoHelper是一个用来存储用户信息的工具类,相当于是SharedPreference,所添加的参数url就是我们app项目中的h5界面的目标文件夹,如下所示:
public class Const {
public interface H5URL{
String URL_LOAN_APPLY_LIST = "file:///android_asset/mobile-page/html/loan-apply/loan-apply.html";
String URL_FINANCING_APPLY_LIST = "file:///android_asset/mobile-page/html/finance-need/finance-need.html";
String URL_FINANCING_APPLY_DETAIL = "file:///android_asset/mobile-page/html/finance-need/finance-need-detail.html";
String URL_LOAN_APPLY_DETAIL = "file:///android_asset/mobile-page/html/loan-apply/loan-apply-detail.html";
}
第二种方式可能会比较复杂一些,但是大多数的操作是在我们Android这边完成,对每一个控件的点击跳转进行提前设定,并且获取到数据,直接塞到h5界面中进行渲染,但是这种方法会大大增加android端的开发工作量,所以还是谨慎选择为好,废话少说,上代码:
//初始化webView
webView = new BaseWebView(this);
webView.getSettings().setSupportZoom(false);
webView.getSettings().setDisplayZoomControls(false);
webView.getSettings().setTextSize(WebSettings.TextSize.NORMAL);
//加载页面
webView.loadUrl("file:///android_asset/mobile-page/html/fun.html");
//注册组件
webView.registerComponents("BaseComponents", new WebComponents());
llLayout.addView(webView);
其中的BaseWebView是我自己封装的一个基础类,里面包含了一些获取焦点的方法等;直接通过loadUrl进行asset目录下的html文件的加载,然后通过注册组件把数据塞到这个界面中进行处理最后再调用addview的方法将这个界面在目标的布局文件中进行显示,下面贴出的代码是WebComponents的逻辑:
/**
* 与HTML5交互的组件
*/
public class WebComponents extends AbsComponents {
@Override
protected ComponentsResult onExec(String action, String callBackMethod, JSONArray params) throws Exception {
L.d("action:" + action + ", callBackMethod:" + callBackMethod
+ ", params:" + params.toString());
//获取数据
if ("data".equals(action)) {
String type = params.getString(0);
if ("page".equals(type)) {
Map<String, String> map = new HashMap<>();
map.put("page", "YSWS");//吃喝玩乐
webView.loadFrameJavaScript("", new Gson().toJson(map), callBackMethod);
}
//获取字典表数据
else if ("type".equals(type)) {
getTypeInfo(params.getString(1), callBackMethod);
}
//获取地区信息
else if ("range".equals(type)) {
getAreaInfo(callBackMethod);
}
//获取数据列表
else if ("list".equals(type)) {
JsonObject jo = new JsonParser().parse(params.getString(1)).getAsJsonObject();
String serviceType = jo.get("serviceTypeOne").getAsString();
String sort = jo.get("sort").getAsString();
String pageSize = jo.get("pageSize").getAsString();
String currentPageNo = jo.get("currentPage").getAsString();
getYswsInfo(serviceType, sort, pageSize, currentPageNo, callBackMethod);
}
}
//点击事件
else if ("click".equals(action)) {
String data = params.getString(0);
JsonObject jo = new JsonParser().parse(data).getAsJsonObject();
Intent intent = new Intent(YswsActivity.this, ChwlDetailActivity.class);
if (jo.has("linkUrl") && StringUtils.isNotBlank(jo.get("linkUrl").getAsString())) {
intent.putExtra(SysCode.INTENT_PARAM.URL, jo.get("linkUrl").getAsString());
} else {
BaseToast.showToastNotRepeat(YswsActivity.this, "url地址为空", SysCode.TOAST_TIME);
return null;
}
intent.putExtra(SysCode.INTENT_PARAM.TITLE, jo.get("placeTypeValue").getAsString() + "详情");
intent.putExtra(SysCode.INTENT_PARAM.ACTIVITY, "YswsActivity");
intent.putExtra("detail", new Gson().fromJson(data, TourBean.class));
startActivity(intent);
}
return null;
}
@Override
protected void onInit(Context ctx, BrowserCore browserCore) {
}
}
逻辑中与action相对应的参数是和h5界面的开发人员协调完成以后,设置的通用参数,在h5界面中可以直接根据这个参数获取相对应的数据和操作!AbsComponent是一个自己封装的塞数据的基础类,逻辑如下所示:
public abstract class AbsComponents implements Components {
private static final String TAG = "Business_Components";
protected static final String OK = JSONObject.quote("OK");
protected static final String ERROR = JSONObject.quote("Error");
protected static final String EMPTY = JSONObject.quote((String)null);
private Context mContext;
private BrowserCore mBrowserCore;
private AbsComponents.ComponentHandler mHandler;
public AbsComponents() {
}
public void initComponents(Context context, BrowserCore browserCore) {
if(null != context) {
this.mContext = context;
}
this.mBrowserCore = browserCore;
this.mHandler = new AbsComponents.ComponentHandler();
this.onInit(this.mContext, browserCore);
}
public final void init(Context context, BrowserCore browserCore) {
}
public final ComponentsResult exec(String arg0, String callBackMethod, String arg1) {
if(TextUtils.isEmpty(arg0)) {
LogUtil.i("Business_Components", "exec action is empty");
return null;
} else {
try {
JSONArray e = new JSONArray(arg1);
return this.onExec(arg0, callBackMethod, e);
} catch (Exception var5) {
LogUtil.e("Business_Components", "errorMsg:" + var5.getMessage(), var5);
return null;
}
}
}
public final void onDestroy() {
}
protected Context getContext() {
return this.mContext;
}
protected BrowserCore getBrowserCore() {
return this.mBrowserCore;
}
protected AbsComponents.ComponentHandler getComponentHandler() {
return this.mHandler;
}
protected void sendHandlerMessage(int what, Object object) {
if(null != this.mHandler) {
Message message = this.mHandler.obtainMessage();
message.what = what;
message.obj = object;
this.mHandler.sendMessage(message);
}
}
protected String parseJsCallback(String jsMethod, String params) {
if(TextUtils.isEmpty(jsMethod)) {
LogUtil.i("Business_Components", "parseJsCallback jsMethod is empty");
return null;
} else {
StringBuilder stringBuilder = new StringBuilder(jsMethod);
stringBuilder.append("(\'");
if(!TextUtils.isEmpty(params)) {
stringBuilder.append(params);
}
stringBuilder.append("\')");
return stringBuilder.toString();
}
}
protected abstract ComponentsResult onExec(String var1, String var2, JSONArray var3) throws Exception;
protected abstract void onInit(Context var1, BrowserCore var2);
protected void onHandleMessage(Message message) {
}
private class ComponentHandler extends Handler {
private ComponentHandler() {
}
public void handleMessage(Message msg) {
super.handleMessage(msg);
AbsComponents.this.onHandleMessage(msg);
}
}
}
在塞数据的过程中会涉及到获取网络数据的方法,这个网络框架的封装 我会在接下来的博文中做详细的表述,仅仅贴出代码,供大家欣赏!(获取地区信息的方法)
/**
* 获取区域
*
* @param jsMethod
*/
private void getAreaInfo(String jsMethod) {
//请求数据
Map<String, String> dataMap = new HashMap<String, String>();
dataMap.put("code", application.getString(SysCode.SHAREDPREFERENCES.CITY_CODING));//从本地数据库获取地市编码360500000000
Map<String, String> map = CommUtil.requestData(ConfigUtil.IS_SECURITY
, SysCode.REQUEST_CODE.GET_CODE, dataMap, getApplicationContext());
mVolleyUtil.init("", map, SysCode.HANDLE_MSG.HANDLER_SECOND,
SysCode.REQUEST_POST, false, false, "", jsMethod);
}
以上就是本人总结的Android和h5之间交互的相关逻辑,如果大家想要代码参考,可以在下面进行留言,多谢!!!!
我是IT老王,热爱编程,热爱生活!!!!!!