敞开成长之旅!这是我参与「日新方案 2 月更文应战」的第 10 天,点击查看活动概况
前言
曾经做电商项目的时分经常和前端打交道,由于许多商品概况页面都是来自H5,避免不了运用WebView。今天就来说说其时怎么运用WebView与前端做交互,有哪几种办法,并就运用中遇到的问题和一些功用的完结做一些阐明,希望能帮助咱们有效避坑。
已然打当作混合开发,那么必定提早了解过WebView这个控,这儿咱们就不提及那些基础的东西,直接来干货。
- Webview中注入JS API
现在市面上很难找到基于Android4.2的机型了吧,所以咱们不必再担心接口走漏的状况。可直接运用addJavascriptInterface的办法,并在每个办法上增加@JavascriptInterface注解即可。这儿需求留意的是addJavascriptInterface办法的第一个入参是该接口,第二个是自定义的实体名。在前端那边就需求运用windows.{自定义实体名}.{接口内办法},这样就达到了前端调用移动端的效果。
//移动端注册前端需求运用的接口
addJavascriptInterface(JsInterface(this), "test")
class JsInterface(private val mContext: Context) {
//供给给前端调用的办法
@JavascriptInterface
fun back() {
(mContext as WebActivity).finish()
}
}
//前端调用移动端办法
windows.test.back()
那么移动端怎么调用前端呢?,运用也很简略:
val json = "张三"
//移动端调用前端供给的onGetData办法,入参json
webView.loadUrl(
"javascript:window.onGetData('"+ json+"')"
)
onGetData()办法便是前端接收的办法,需求留意的是loadUrl办法中由于传入的是字符串,在onGetData办法入参时需求运用单引号进行分割,不然编译器报错。
提到这儿不得不说的便是传图片、视频等文件的功用,以往都是运用前端调用原生办法,经过api翻开相机回来图片再以byte数字的办法回来给前端。但中途遇到一个状况便是前端的架构中运用的另外一种办法 openfile,曾经没遇到没关系,其实便是运用Webview设置WebChromeClient,前端运用openfile的时分Android端就会在onShowFileChooser办法中收到回调,这时分需求外部声明并赋值中onShowFileChooser中传回的ValueCallback,并初始化翻开相机获取图片信息。
private var valueCallback: ValueCallback<Array<Uri?>>? = null
webChromeClient =object :WebChromeClient(){
override fun onShowFileChooser(
p0: WebView?,
filePathCallback: ValueCallback<Array<Uri?>>?,
p2: FileChooserParams?
): Boolean {
valueCallback = filePathCallback
//初始化获取图片相关
initPhoto()
return true
}
}
接着,运用刚刚得到的valueCallback传入得到的文件,这儿文件最终的格局必须运用Uri形式供给。
fun initPhoto() {
......
override fun onResult(result: List<Uri?>) {
valueCallback?.onReceiveValue(result)
valueCallback==null
}
override fun onCancel() {
valueCallback?.onReceiveValue(null)
valueCallback=null
}
}
这样前端就能在对应的回调中拿到移动端传过去的文件,需求留意的是valueCallback用后需求收回,不然下次运用会出现问题。
- JsBridge
一款三方混合开发工具,装备少,两头都需求接入该三方库,运用简略:
repositories {
maven { url "https://jitpack.io" }
}
dependencies {
compile 'com.github.lzyzsd:jsbridge:1.0.4'
}
需求留意的是,此时在Xml布局中要运用包名为:com.github.lzyzsd.jsbridge.BridgeWebView的webview,
//移动端供给test1办法
webView.registerHandler("test1", new BridgeHandler() {
@Override
public void handler(String data, CallBackFunction function) {
function.onCallBack("submitFromWeb exe, response data from Java");
}
});
//前端调用
WebViewJavascriptBridge.callHandler('test1', {'param': str1}, function(responseData) {
document.getElementById("show").innerHTML = "send get responseData from java, data = " + responseData
}
);
//前端注册test2办法
WebViewJavascriptBridge.registerHandler("test2", function(data, responseCallback) {
document.getElementById("show").innerHTML = ("data from Java: = " + data);
var responseData = "Javascript Says Right back aka!";
responseCallback(responseData);
});
//移动端调用test2办法
webView.callHandler("test2", new Gson().toJson(user), new CallBackFunction() {
@Override
public void onCallBack(String data) {
}
});
这种办法还有一个优势便是前端不必考虑ios适配问题,只需求ios也接入该库就能满足仅需求一套代码就能适配两头的优点。
总结
Webview中注入JS API办法是官方控件供给的api,需求独自为前端注册一个接口用于前端拜访,可接收回来值,前端需求针对Android端进行适配。运用JsBridge办法网上有好几个三方库都可完结,各个端口需求接入同一个三方库,库里现已封装好各办法,前端可以一套代码完结移动端的适配。
敞开成长之旅!这是我参与「日新方案 2 月更文应战」的第 10 天,点击查看活动概况