实现的逻辑大体是这样的,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 method url = url.substring(protocolPrefix.length()); //Decode the url string HashMap callInfo = JsonUtil.read(url,HashMap.class); if (callInfo == null) { //TODO:提示调用解析失败 return false; } //Get function name. It is a required input Object 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 + "')"); else webView.loadUrl("javascript:" +functionName + "()"); } public static JsFunctions getInstance() { return instance; } } 好了,就到这里,有什么不足请多多指正。。。当然,开发完APP也是需要进行全方位的检测:www.ineice.com
|