以下只是我解决问题过程中的一点点个人总结,点滴积累,贵在坚持,感谢你的阅览!
前言:前段时间遇到的一个新需求:后端提供一个可后台更新的 html5 给应用端,该 html5 提供中间层校正操作
应用端获取初始数据后,将初始数据传参给 html5,html5 返回应用端一个 url ,应用端访问该 url 获取网络返回值,再将该返回值传给 html5 ,html5 再返回应用端最终数据,应用端显示该数据;
表述能力实在是有点欠缺,做完这个功能后,时隔半个月再来写这篇博客,实在是没那么记忆深刻了,很多当时踩过的坑,现在都不记得了;
要实现此功能,就需要用到 android 和 html5 互相传参并接受返回值的相关知识,本人之前对这些操作没有了解,通过两周的学习和摸索,实现了该需求,在此总结一下;
调试过程中,log 信息过滤关键字使用 chromium(android 5.0 及之后使用此关键字);
1.认真阅读后台提供的接口文档和 html5 文件,找到接口名和参数名、参数类型,搞清楚是 post 请求还是 get 请求,请求顺序是怎样的;
2.看完接口文档,发现用到的是 post 请求,请求顺序为:(不知道的可以直接找后台,让提供提供给你)
3.废话不多说,看代码是最直接的;
3.1 新建接口
public interface nativeApi {
void httpProxy(String url, String method, String header, String body);
void onH5FanyiResult(String str);
}
3.2 新建 WebView 类成员变量并初始化
private android.webkit.WebView mWebViewShowHtml;
mWebViewShowHtml = (WebView) findViewById(R.id.html5);
WebSettings mHtmlWebSettings = mWebViewShowHtml.getSettings();
mHtmlWebSettings.setJavaScriptEnabled(true);
3.3 新建 WebViewClient 类
class TranslateWebViewClient extends WebViewClient {
//在开始加载网页时会回调
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
//在结束加载网页时会回调
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
String content = filterInputContent(mInputStr);
content = BaseUtil.getHandledParam(content);
Log.i(TAG,"要翻译的内容 : " + content);
mWebViewShowHtml.loadUrl("javascript:onNativeFanyi('" + content + "')");
//首次传参一定一定要在 onPageFinished 方法中执行,否则传参时 html5 还没加载完就传参,返回值必然会是空值
//另外参数要对单引号和双引号做特殊编码、解码处理,否则会报异常
}
//加载错误的时候会回调,在其中可做错误处理,比如再请求加载一次,或者提示404的错误页面
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
super.onReceivedError(view, errorCode, description, failingUrl);
mOutputStr = HTML_TRANSLATE_ERROR;
}
//当接收到https错误时,会回调此函数,在其中可以做错误处理
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
super.onReceivedSslError(view, handler, error);
mOutputStr = HTML_TRANSLATE_ERROR;
}
//在每一次请求资源时,都会通过这个函数来回调
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
return null;
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}
3.4 传参
try {
Log.i(TAG,"开始进行翻译");
mWebViewShowHtml.addJavascriptInterface(new nativeApi() {
@android.webkit.JavascriptInterface
@Override
public void httpProxy(String url, String method, String header, String body) {
Log.d(TAG,"httpProxy url : " + url);
Log.d(TAG,"httpProxy method : " + method);
Log.d(TAG,"httpProxy header : " + header);
Log.d(TAG,"httpProxy body : " + body);
Map<String ,String> paramsHtml = BaseUtil.json2Map(body);
Map<String, String> headerHtml = BaseUtil.json2Map(header);
// 进行 http 网络请求,获取翻译结果
BfcHttp.post(mContext, url, paramsHtml, headerHtml, new StringCallBack() {
@Override
public void onResponse(String response) {
Log.d(TAG,"BfcHttp response : " + response);
response = BaseUtil.getHandledParam(response);
mWebViewShowHtml.loadUrl("javascript:onNativeRsJson('" + response + "')");
}
}, new IBfcErrorListener() {
@Override
public void onError(BfcHttpError error) {
Log.d(TAG,"BfcHttp error : " + error.toString());
mOutputStr = HTML_TRANSLATE_ERROR;
}
});
}
@android.webkit.JavascriptInterface
@Override
public void onH5FanyiResult(String str) {
if (!TextUtils.isEmpty(str)) {
mOutputStr = str;
mIsFinish = true;
} else {
mOutputStr = HTML_TRANSLATE_ERROR;
mIsFinish = true;
mTranslateException = new TranslateException(
TranslateException.TRANSLATE_EXCPTION_CODE.TRANSLATE_EXCEPTION_CODE_TRANSLATE_FAILED);
}
}
}, "nativeApi");
/*mWebViewShowHtml.loadUrl("file:///android_asset/translate.html");*/
mWebViewShowHtml.loadUrl("file:///" + HtmlFileUtil.getLocalHtmlFilePath());
mWebViewShowHtml.setWebViewClient(new TranslateWebViewClient());
} catch (Exception e) {
mOutputStr = HTML_TRANSLATE_ERROR;;
mIsFinish = true;
mTranslateException = new TranslateException(TranslateException.TRANSLATE_EXCPTION_CODE.TRANSLATE_EXCEPTION_CODE_TIMEOUT);
}