APP和Js之间的相互调用方法

前言:

在项目中有时候需要APP和H5之间相互调用方法来实现某些功能,本文主要介绍Android和iOS是怎么实现相互调用对方的方法。

一、APP调用H5的方法

将APP生成的信息,以基本数据类型或者Json字符串(可以传比较多的信息)的形式传给H5。

Android——通过webview重新loadUrl,进行加载对应的H5的方法

webView.loadUrl(“javascript:methodName(parameterValues)”;

举例说明:

/**
 * APP通过该方法来调用H5的方法
 * @param method 方法名 
 * @param param 方法参数
 */

    private void reloadJs(String method, String param) {
        String url = String.format("javascript:%s(\"%s\")", method, param);
        webview.loadUrl(url);
    }

在需要的地方调用reloadJs

在H5中相应的存在以下方法:

//Android调用该方法来实现改变H5的内容
function alert(message){
document.getElementById("change").innerHTML = message;
}

iOS——利用了webview提供的方法进行加载对应的H5的方法

 [self.webView stringByEvaluatingJavaScriptFromString:@"methodName(parameterValues)"];

举例说明:

[self.webView stringByEvaluatingJavaScriptFromString:@"alert(\"iOS change javascript to message for H5\")"];

在H5添加alert方法即可 

 function alert(message){
      document.getElementById("change").innerHTML = message;
    }

二、H5调用APP的方法——APP来实现一些功能

H5将所需要的参数通过JSon字符串的形式传给APP

Android——根据webview原生方法实现该功能

1、通过下面的方法将webview的接口传给H5
 @param object the Java object to inject into this WebView's JavaScript
* @param name the name used to expose the object in JavaScript
webview.addJavascriptInterface(Object object, String name));

在本项目中代码如下:

 webview.addJavascriptInterface(new JsAction(), "action");
2、在JsAction类中添加相应的接口方法

android原生提供了一种注解方式@JavascriptInterface。只要在JsAction的类里面定义的方法都加上@JavascriptInterface即可。

 private class JsAction {

        @JavascriptInterface //H5调用Android的该方法
        public void toast(final String jsonString) {
            //注意@JavascriptInterface 下的该方法和当前activity并不是同一个线程,所以增加要将H5的调用和回调到H5的代码都写到runOnUiThread。否则会抛出以下异常
            runOnUiThread(new Runnable() {
               @Override
              public void run() {
            JSONObject object = null;
            try {
                object = new JSONObject(jsonString);
            } catch (JSONException e) {
                e.printStackTrace();
            }
            AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
            builder.setTitle("H5调用Android显示对话框");
            if (object != null) {
                builder.setMessage(object.optString("message", ""));
            }
            builder.setNegativeButton(android.R.string.ok, null);
            AlertDialog dialog = builder.create();
            dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
                @Override
                public void onDismiss(DialogInterface dialog) {
                    //在dialog消息的时候,将修改H5的内容
                    reloadJs("alert", "iOS change javascript to message for H5");
                }
            });
            dialog.show();
               }
             });


        }
    }

在H5调用的方法中添加如下代码即可

    //H5调用Android的方法来显示dialog
    function toast(){
        window.action.toast("{\"message\":\"From H5 message\"}");
    }

@JavascriptInterface 下的该方法和当前activity并不是同一个线程,所以增加要将H5的调用和回调到H5的代码都写到runOnUiThread。否则会抛出以下异常

05-17 16:11:00.847 13875-14010/com.j1 E/AndroidRuntime: FATAL EXCEPTION: JavaBridge
    Process: com.j1, PID: 13875
    java.lang.RuntimeException: java.lang.Throwable: A WebView method was called on thread 'JavaBridge'. All WebView methods must be called on the same thread. (Expected Looper Looper (main, tid 2) {839b89} called on Looper (JavaBridge, tid 349) {a0a3877}, FYI main Looper is Looper (main, tid 2) {839b89})
        at android.webkit.WebView.checkThread(WebView.java:2486)
        at android.webkit.WebView.loadUrl(WebView.java:938)
        at com.j1.MainActivity.reloadJs(MainActivity.java:89)
        at com.j1.MainActivity.access$100(MainActivity.java:18)
        at com.j1.MainActivity$JsAction$1.onDismiss(MainActivity.java:76)
        at android.app.Dialog$ListenersHandler.handleMessage(Dialog.java:1361)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:164)
        at android.os.HandlerThread.run(HandlerThread.java:65)
     Caused by: java.lang.Throwable: A WebView method was called on thread 'JavaBridge'. All WebView methods must be called on the same thread. (Expected Looper Looper (main, tid 2) {839b89} called on Looper (JavaBridge, tid 349) {a0a3877}, FYI main Looper is Looper (main, tid 2) {839b89})
        at android.webkit.WebView.checkThread(WebView.java:2476)
        at android.webkit.WebView.loadUrl(WebView.java:938) 
        at com.j1.MainActivity.reloadJs(MainActivity.java:89) 
        at com.j1.MainActivity.access$100(MainActivity.java:18) 
        at com.j1.MainActivity$JsAction$1.onDismiss(MainActivity.java:76) 
        at android.app.Dialog$ListenersHandler.handleMessage(Dialog.java:1361) 
        at android.os.Handler.dispatchMessage(Handler.java:105) 
        at android.os.Looper.loop(Looper.java:164) 
        at android.os.HandlerThread.run(HandlerThread.java:65) 

IOS——通过UIWebview的delegate

主要通过在(BOOL)webView: shouldStartLoadWithRequest:navigationType:协议方法中,通过解析request,得到iOS方法的信息。

举例说明:

-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
    
    NSURL *url = [request URL];
    NSString *method = [url host];
    NSString *queryString = [url query];
    if (queryString == nil) {
        [self trigger:method jsonParam:nil];
        return YES;
    }
    [self trigger:method jsonParam:nil];
    return YES;
}

然后直接调用到iOS已有的方法进行调用到对应的方法即可

-(void)trigger:(NSString *)method jsonParam:(NSString *)jsonParam{
    
    NSString * methodName = [NSString stringWithFormat: jsonParam!=nil?@"%@:param:":@"%@",method];
    NSLog(@"methodName = %@",methodName);
    SEL sel = NSSelectorFromString(methodName);
    if( [self respondsToSelector:sel] ) {
        [self performSelector:sel  withObject:jsonParam];        
    }
}

在H5通过增加iframe来实现回调到iOS协议方法

var  src = schemename + action +"?"+"message=2"; //组装成示例中的url的样式
var iframe = document.createElement("iframe");
iframe.src = src;
document.documentElement.appendChild(iframe);
iframe.parentNode.removeChild(iframe);
iframe = null;


具体的代码可以去下载。

代码具体实现的就是:点击按钮,实现H5调用APP的方法,同时APP去调用H5的方法来改变H5的有关内容

Android代码下载地址:点击打开链接

iOS代码下载地址:点击打开链接

猜你喜欢

转载自blog.csdn.net/nihaomabmt/article/details/80347945