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){
}
iOS——利⽤了webview提供的⽅法进⾏加载对应的H5的⽅法
[self.webView stringByEvaluatingJavaScriptFromString:@"methodName(parameterValues)"];
举例说明:
[self.webView stringByEvaluatingJavaScriptFromString:@"alert(\"iOS change javascript to message for H5\")"];
在H5添加alert⽅法即可
function alert(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 = ate();
dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
//在dialog消息的时候,将修改H5的内容
reloadJs("alert", "iOS change javascript to message for H5");
原生js和js的区别
}
});
dialog.show();
}
});
}
}
在H5调⽤的⽅法中添加如下代码即可
//H5调⽤Android的⽅法来显⽰dialog
function toast(){
ast("{\"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 thr        at android.webkit.WebView.checkThread(WebView.java:2486)
at android.webkit.WebView.loadUrl(WebView.java:938)
at com.loadJs(MainActivity.java:89)
at com.j1.MainActivity.access$100(MainActivity.java:18)
at com.j1.MainActivity$Dismiss(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        at android.webkit.WebView.checkThread(WebView.java:2476)
at android.webkit.WebView.loadUrl(WebView.java:938)
at com.loadJs(MainActivity.java:89)
at com.j1.MainActivity.access$100(MainActivity.java:18)
at com.j1.MainActivity$Dismiss(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)navigation
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 = ateElement("iframe");
iframe.src = src;
document.documentElement.appendChild(iframe);
veChild(iframe);
iframe = null;
具体的代码可以去下载。
代码具体实现的就是:点击按钮,实现H5调⽤APP的⽅法,同时APP去调⽤H5的⽅法来改变H5的有关内容Android代码下载地址:
iOS代码下载地址:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。