App Webview与内嵌web交互实现
实现的逻辑大体是这样的,APP的webview可以拦截请求的链接地址,通过与内嵌界面约定请求前缀(如:webjs2app://),后接请求内容。 请求内容如下: {"functionName":"sayHello',"args":["haha"],"success":"onSuccess","error":"onError"} 是一个Json字串,包括信息有调用的App接口方法名、传的参数、调用成功后回调的js方法名,调用失败后回调的js方法名。抽象的很到位,可以做到通用。 最终web请求接口地址如:webjs2app://{"functionname":"sayHello',"args":["haha"],"success":"onSuccess","error":"onError"},App webview收到由webjs2app://打头的请求地址时,就会把后面的请求内容解析出来。。。上代码。 刚刚链接里面已经有IOS和Web的代码了,并且说明的明白。我这里补充一下Android端对应的实现。 第一步,重写一下 shouldOverrideUrlLoading,拦截约定的请求。 private String protocolPrefix = "webjs2app://";//这个前缀要用小写,因为webview会自动将请求协议类型转成小写的。 mWebView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { return processURL(url); } 。。。。 } 第二步,解析请求接口数据 private boolean processURL(String url) {int i = url.indexOf(protocolPrefix);System.out.println(url);if (url.indexOf(protocolPrefix) == 0) {//strip protocol from the URL. We will getinput to call a native methodurl = url.substring(protocolPrefix.length()); //Decode the url stringHashMap callInfo = JsonUtil.read(url,HashMap.class); if (callInfo == null) {//TODO:提示调用解析失败return false;}//Get function name. It is a required inputObject functionName =callInfo.get("functionName");if (functionName == null) {//TODO:提示未找到调用方法return false;}Object success =callInfo.get("success");Object error =callInfo.get("error");Object args =callInfo.get("args"); callNativeFunction((String) functionName,args, success, error);return false;} return true;} 第三步,利用java反射,调用接口。 /*** 方法接口调用** @param functionName* @param args* @param success* @param error*/private void callNativeFunction(StringfunctionName, Object args, Object success, Object error) {try {//使用反射,注意不能对JsFunctions类做混淆处理Method method =JsFunctions.class.getMethod(functionName, WebView.class, Object.class,Object.class, Object.class);Object invoke =method.invoke(JsFunctions.getInstance(),mWebView, args, success, error);} catch (NoSuchMethodException e) {//TODO:提示未找到调用方法} catch (InvocationTargetException e) {e.printStackTrace();} catch (IllegalAccessException e) {//TODO:提示权限访问e.printStackTrace();} } 第四步,接口处理类 public class JsFunctions { /*** 单例*/private static JsFunctions instance = newJsFunctions(); /*** sayHello接口* @param webView* @param args* @param successFunc* @param errorFunc*/public void sayHello(WebView webView,Object args, Object successFunc, Object errorFunc) {if (args != null) {Object name = ((ArrayList) args).get(0);Log.d(name.toString());if (successFunc != null)callJSFunction(webView,successFunc.toString(), args);} else {if (errorFunc != null)callJSFunction(webView,errorFunc.toString(), args);}} /*** 回调处理* @param webView* @param functionName* @param args*/public void callJSFunction(WebView webView,String functionName, Object args) {String argsJsonStr = null;if (args != null) {argsJsonStr = JsonUtil.write2String(args);}if (argsJsonStr != null)webView.loadUrl("javascript:" +functionName + "('" + argsJsonStr + "')");elsewebView.loadUrl("javascript:" +functionName + "()"); } public static JsFunctions getInstance() {return instance;}} 好了,就到这里,有什么不足请多多指正。。。当然,开发完APP也是需要进行全方位的检测:www.ineice.com
页:
[1]