uiwebviewjsbridge 前端 该怎么兼容ios和安卓的input

自白:H5,JavaScript从未接触过,有一定的Android基础
目的:一张图,解放自己的记忆~深入的知识很多大牛已经总结过啦
前记:刚接触Android与前端的交互,一直不明白具体原理是啥米,看着别人熟练的开发着总觉得特别高深似的(貌似每次没接触过的东西,都觉得别人特别牛,有木有~)。今天狠狠心,看了看区长的博客,茅塞顿开,总结了一下区长大人的文章和示例,感谢区长大人~这是区长大人的牛逼博客地址:http://blog.csdn.net/sbsujjbcy/article/details/,里面有详细的代码和原理解析
内容:我脑子总是不好使,超级羡慕那些说“只要理解了就不可能忘记”的牛逼人士,谁让我的脑袋只有芝麻大小,还是找找自己的理解记忆方式吧~
上图和示例吧~
结合图形的步骤标号逻辑,我们来给出示例进行分析:
1.必须先确定Url的具体格式,是为了统一前端与Android的互相调用,也就是干活前先得签订一个协议。参考http制定的协议为:jsbridge:
&button onclick=&JSBridge.call('bridge','showToast',{'msg':'Hello JSBridge'},function(res){alert(JSON.stringify(res))})&&
测试showToast
3.JavaScript文件命名为JSBridge.js, 第2步中的JSBridge.call即为调用JSBridge.js中的call方法,后面带了四个参数
call: function (obj, method, params, callback) {
console.log(obj+& &+method+& &+params+& &+callback);
var port = Util.getPort();
console.log(port);
this.callbacks[port] =
var uri=Util.getUri(obj,method,params,port);
console.log(uri);
window.prompt(uri, &&);
JSBridge.js中的call方法,最后调用了window.prompt方法,这个方法就是触发Android端webChromeClient的回调函数用的
Android了。
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
result.confirm(JSBridge.callJava(view,message));
5.Android中会定义一个类JSBridge.java来管理暴露给前端使用的函数。这个类有两个功能:1)暴露给前端的函数的动态注册功能。
2)解析前端信息,调用了Android端对应的函数,这个示例中是:showToast函数
解析前端的信息,获取前端调用的函数名:Uri uri = Uri.parse(uriString);
className = uri.getHost();
param = uri.getQuery();
port = uri.getPort() + &&;
String path = uri.getPath();
HashMap& String, Method& methodHashMap = exposedMethod.get(className);Method method = methodHashMap.get(methodName);
通过获取的函数名,这里是showToast,调用Android端的showToast函数
method.invoke(null,webView,new JSONObject(param),new Callback(webView,port));//
public static void showToast(WebView webView, JSONObject param, final JSBridge.Callback callback){
String message = param.optString(&msg&);
Toast.makeText(webView.getContext(),message,Toast.LENGTH_LONG).show();
if(null != callback){
JSONObject object = new JSONObject();
object.put(&key&,&value&);
object.put(&key1&,&vaule1&);
callback.apply(getJSONObject(0,&ok&,object));
}catch (Exception e){
e.printStackTrace();
完整的流程就顺利的串起来啦,发现其实要简单串起来也没那么难对不对,以后再慢慢研究其中的奥妙吧~
欢迎大家沟通交流,如有错误也欢迎指正~
本文已收录于以下专栏:
相关文章推荐
对js与android交互进行的封装,可自定义协议,没有js注入漏洞,安全可靠,兼容android所有系统版本
在Android中,JSBridge已经不是什么新鲜的事物了,各家的实现方式也略有差异。大多数人都知道WebView存在一个漏洞,见WebView中接口隐患与手机挂马利用,虽然该漏洞已经在Androi...
在Android中,JSBridge已经不是什么新鲜的事物了,各家的实现方式也略有差异。大多数人都知道WebView存在一个漏洞,见WebView中接口隐患与手机挂马利用,虽然该漏洞已经在Androi...
前面的一篇文章Android ORM系列之ActiveAndroid 介绍了ActiveAndroid的使用方法,但是ActiveAndroid有一个很明显的缺点,就是所有的实体类必须继承Model类...
概述在进行具体编码前 ,我们先分析下一般商业APP对WebView的需求:
可加载本地和云端H5
拥有cookie持久能力
添加公共参数
回退前进功能
Js与本地navtive交互
拥有加载默认错误页...
最近在做一个论坛项目,项目当中涉及了Android Native与Html5之间的交互操作,其实主要也就是Java端与JavaScript端的交互工作,由于本人新手一枚,此前并无此方面的经验,所以就在...
上一篇文章对greenDao有一个整体的把握 Android ORM系列之GreenDao最佳实践。这篇文章将重点介绍GreenDao的关联关系的映射以及实体类的生成。在GreenDao中,实体类的生...
在Android中,JSBridge已经不是什么新鲜的事物了,各家的实现方式也略有差异。大多数人都知道WebView存在一个漏洞,见WebView中接口隐患与手机挂马利用,虽然该漏洞已经在Androi...
他的最新文章
讲师:刘文志
讲师:陈伟
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)iOS中Objective-C与JavaScript之间相互调用的实现(实现了与Android相同的机制)
最近在iOS项目中需要使用到oc与js之间的相互调用,而且要求是实现方式必须与中的相同,方便js中统一处理。于是在对第三方库WebViewscriptBridge进行研究之后,仿照Android中的WebView与JS的交互机制,实现了一个,在这里分享给大家。
首先要说明的是,在iOS中js调用Objective-C的代码只能通过重定向的形式进行,即js中通过修改iframe的src,或者直接跳转到一个url,在Objective-C中通过UIWebView的
webView:shouldStartLoadWithRequest:navigationType:方法拦截这个跳转,然后通过解析跳转的url获取js需要调用的方法名和参数。而在Android中,只需要调用WebView的addJavascriptInterface方法,将一个js对象绑定到一个java类,在类中实现相应的函数,当js需要调用java的方法时,只需要直接在js中通过绑定的对象调用相应的函数即可。
显然Android中js交互的方式要比iOS上方便得多,因此,我们可以在iOS上实现一套与Android相类似的机制。下面先说明一下实现的原理,要在js中直接通过绑定的对象调用相应的函数,那么就需要在js中添加相应的代码,但是为了确保与Android的一致性,js代码应该在客户端以注入的形式加入。所以,我们先实现一下需要注入的代码:
;(function() {
var messagingIframe,
bridge = 'external',
CUSTOM_PROTOCOL_SCHEME = 'jscall';
if (window[bridge]) { return }
function _createQueueReadyIframe(doc) {
messagingIframe = doc.createElement('iframe');
messagingIframe.style.display = 'none';
doc.documentElement.appendChild(messagingIframe);
window[bridge] = {};
var methods = ["test1", "test2"];
for (var i=0;i<methods.i++){
var method = methods[i];
var code = "(window[bridge])[method] = function " + method + "() {messagingIframe.src = CUSTOM_PROTOCOL_SCHEME + ':' + arguments.callee.name + ':' + encodeURIComponent(JSON.stringify(arguments));}";
eval(code);
//创建iframe,必须在创建external之后,否则会出现死循环
_createQueueReadyIframe(document);
//通知js开始初始化
//initReady();
在以上代码中,我们在网页中添加了一个iframe,使得改变iframe的src时webview可以捕捉到重定向请求,使用这种方式进行重定向,相比直接修改网页的url要安全得多。同时设置了一个external对象,并为该对象绑定了test1、test2方法,当这两个方法执行时,会修改iframe的src,并将要调用的方法和参数以url的形式来构造。然后,我们需要在webview完成网页加载的时候进行注入,实现以下委托:
- (void)webViewDidFinishLoad:(UIWebView *)webView {
//js是否注入成功
if (![[webView stringByEvaluatingFromString:[NSString stringWithFormat:@"typeof window.%@ == 'object'", kBridgeName]] isEqualToString:@"true"]) {
NSBundle *bundle = _resourceBundle ? _resourceBundle : [NSBundle mainBundle];
NSString *filePath = [bundle pathForResource:@"WebViewJsBridge" ofType:@"js"];
NSString *js = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
[webView stringByEvaluatingJavaScriptFromString:js];
注意,以上代码在注入前需要判断是否已经注入,避免重复注入。接下来,我们可以再实现一个webview的委托来拦截重定向事件:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSURL *url = [request URL];
NSString *requestString = [[request URL] absoluteString];
if ([requestString hasPrefix:kCustomProtocolScheme]) {
NSArray *components = [[url absoluteString] componentsSeparatedByString:@":"];
NSString *function = (NSString*)[components objectAtIndex:1];
NSString *argsAsString = [(NSString*)[components objectAtIndex:2]
stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSData *argsData = [argsAsString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *argsDic = (NSDictionary *)[NSJSONSerialization JSONObjectWithData:argsData options:kNilOptions error:NULL];
//将js的数组转换成objc的数组
NSMutableArray *args = [NSMutableArray array];
for (int i=0; i<[argsDic count]; i++) {
[args addObject:[argsDic objectForKey:[NSString stringWithFormat:@"%d", i]]];
//调用oc方法,忽略警告
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
SEL selector = NSSelectorFromString([function stringByAppendingString:@":"]);
CLog(@"sel:%@, args:%@", function, args);
if ([self respondsToSelector:selector]) {
[self performSelector:selector withObject:args];
return NO;
return YES;
以上代码中对重定向的url进行了判断,如果符合我们事先定义的协议,就进行解析,否则就进行跳转。解析的时候以冒号分隔,取出函数名和参数列表,并调用相应的方法。至此,我们就在iOS中实现了与Android相同的调用机制。
但以上方法的缺点是还没有达到Android中的方便程度,最理想的方法是当进行js注入时,动态设置待绑定的对象,同时动态获取当前类的实例方法,并生成相应的js代码。这就完全实现了Android中的绑定机制。这个实现起来并不难,有兴趣的朋友可以试试。
为了方便大家使用,我将以上代码封装成了一个类,具体的使用方法见Demo。
需要注意的是:
1. 在实际应用中可能出现js执行顺序的问题,如果网页中的js在注入前先获取绑定的对象进行保存,是无法获取到的,因为这时候待绑定的对象为空。这就需要网页中js的初始化在注入之后,因此在上文代码中有一个initReady方法。
2. 由于performSelector最多只能包含两个参数,因此例子中是通过数组来传递参数列表的。
如果大家觉得对自己有帮助的话,还希望能帮顶一下,谢谢:)
个人博客:https://blog.csdn.net/zhaoxy2850
本文地址:https://blog.csdn.net/zhaoxy_thu/article/details/
转载请注明出处,谢谢!转载自:http://blog.csdn.net/yanghua_kobe/article/details/8209751
本篇为大家介绍一个优秀的开源小项目:。
它优雅地实现了在使用UIWebView时JS与ios 的ObjC nativecode之间的互调,支持消息发送、接收、消息处理器的注册与调用以及设置消息处理的回调。
就像项目的名称一样,它是连接UIWebView和Javascript的bridge。在加入这个项目之后,他们之间的交互处理方式变得很友好。
在native code中跟UIWebView中的js交互的时候,像下面这样:
而在UIWebView中的js跟native code交互的时候也变得很简洁,比如在调用处理器的时候,就可以定义回调处理逻辑:
[javascript]&
一起来看看它的实现吧,它总共就包含了三个文件:
它们是以如下的模式进行交互的:
很明显:WebViewJavascriptBridge.js.txt主要用于衔接UIWebView中的web page,而WebViewJavascriptBridge.h/m则主要用于与ObjC的native code打交道。他们作为一个整体,其实起到了一个“桥梁”的作用,这三个文件封装了他们具体的交互处理方式,只开放出一些对外的涉及到业务处理的API,因此你在需要UIWebView与Native code交互的时候,引入该库,则无需考虑太多的交互上的问题。整个的Bridge对你来说都是透明的,你感觉编程的时候,就像是web编程的前端和后端一样清晰。
简单地罗列一下它可以实现哪些功能吧:
出于表达上的需要,对于UIWebView相关的我就称之为UI端,而objc那端的处理代码称之为Native端。
(1)&&&UI端在初始化时支持设置消息的默认处理器(这里的消息指的是从Native端接收到的消息)
(2)&&&从UI端向Native端发送消息,并支持对于Native端响应后的回调处理的定义
(3)&&&UI端调用Native定义的处理器,并支持Native端响应后的回调处理定义
(4)&&&UI端注册处理器(供Native端调用),并支持给Native端响应处理逻辑的定义
【2】 Native端
(1)&&&Native端在初始化时支持设置消息的默认处理器(这里的消息指的是从UI端发送过来的消息)
(2)&&&从Native端向UI端发送消息,并支持对于UI端响应后的回调处理逻辑的定义
(3)&&&Native端调用UI端定义的处理器,并支持UI端给出响应后在Native端的回调处理逻辑的定义
(4)&&&Native端注册处理器(供UI端调用),并支持给UI端响应处理逻辑的定义
UI端以及Native端完全是对等的两端,实现也是对等的。一段是消息的发送端,另一段就是接收端。这里为引起混淆,需要解释一下我这里使用的“响应”、“回调”在这个上下文中的定义:
(1)&&&响应:接收端给予发送端的应答
(2)&&&回调:发送端收到接收端的应答之后在接收端调用的处理逻辑
下面来分析一下源码:
WebViewJavascriptBridge.js.txt:
主要完成了如下工作:
(1) 创建了一个用于发送消息的iFrame(通过创建一个隐藏的ifrmae,并设置它的URL 来发出一个请求,从而触发UIWebView的shouldStartLoadWithRequest回调协议)
(2) 创建了一个核心对象WebViewJavascriptBridge,并给它定义了几个方法,这些方法大部分是公开的API方法
(3) 创建了一个事件:WebViewJavascriptBridgeReady,并dispatch(触发)了它。
对于(1),相应的代码如下:
[javascript]&
对于(2)中的WebViewJavascriptBridge,其对象拥有如下方法:
方法的实现:
[javascript]&
涉及到的两个内部方法:
[javascript]&
还有两个js方法是供native端直接调用的方法(它们本身也是为native端服务的):
[javascript]&
最后还有一段代码就是,定义一个事件并触发,同时设置设置上面定义的WebViewJavascriptBridge对象为事件的一个属性:
[javascript]&
Native端实现
其实大致跟上面的类&#20284;,只是因为语法不同(所以我上面才说两端是对等的):
WebViewJavascriptBridge.h/.m
它其实可以看作UIWebView的Controller,实现了UIWebViewDelegate协议:
方法的实现其实是跟前面类&#20284;的,这里我们只看一下UIWebView的一个协议方法
shouldStartLoadWithRequest:
[javascript]&
项目运行截图:
本文已收录于以下专栏:
相关文章推荐
一、导入第三方类库:
JsBridge类库地址。
二、Android Studio导入第三方类库说简单简单,说难也难。
查看类库结构:
导入步骤:
1)先复制上述第三方类库到app平级处:如下
在移动开发中,我们必不可少需要使用Web来代替部分Native,也就是业内所说的Hybrid App。
一、基本信息介绍
Ios 和 Android两种终端与Javascript的通信机制有些不同...
本篇为大家介绍一个优秀的开源小项目:WebViewJavascriptBridge。
它优雅地实现了在使用UIWebView时JS与ios 的ObjC nativecode之间的互调,支持消...
本篇为大家介绍一个优秀的开源小项目:WebViewJavascriptBridge。 它优雅地实现了在使用UIWebView时JS与ios 的ObjC nativecode之间的互调,支持消息发送、接...
本篇为大家介绍一个优秀的开源小项目:WebViewJavascriptBridge。
它优雅地实现了在使用UIWebView时JS与ios 的ObjC nativecode之间的互调,支持消息发...
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;
本篇为大家介绍一个优秀的开源小项目:WebViewJavascriptBridge。 它优雅地实现了在使用UIWebView时...
原文传送门:http://blog.csdn.net/yanghua_kobe/article/details/8209751
本篇为大家介绍一个优秀的开源小项目:WebViewJavascript...
本篇为大家介绍一个优秀的开源小项目:WebViewJavascriptBridge。
它优雅地实现了在使用UIWebView时JS与ios 的Objective-C nativecod...
本篇为大家介绍一个优秀的国人开发开源小项目:WebViewJavascriptBridge。
下载WebViewJavascriptBridge地址
它优雅地实现了在使用UIWebView时JS与...
马上要开始一个关于体育赛事直播的新项目,数据逻辑比较复杂,数据处理这块如果按照以前的积累无疑会选择 AFNetworking+JSONKit+MagicalRecord.这种模式使用起来轻便,可定制性...
他的最新文章
讲师:刘文志
讲师:陈伟
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)1281人阅读
----IOS / Swift / Obj-c(5)
----React(6)
android webview
js调用java的方式
1.java通过注解@JavascriptInterface导出方法, js通过window.别名.方法名调用方法
2.拦截url方式,通过shouldOverrideUrlLoading实现
java调用js的方式
1.webview.loadUrl,&可以通过回调实现获取返回&#20540;
2.webview.evaluateJavascript 4.4及以上版本才能使用
3.通过反射实现stringByEvaluatingJavaScriptFromString方法
通过shouldInterceptRequest来实现
IOS UIWebview
js调用objc
1.拦截url方式,webview:shouldStartLoadWithRequest:navigationType
2.通过JavascriptCore实现
objc调用js
1.stringByEvaluatingJavaScriptFromString
2.JavaScriptCore
通过NSURLProtocol拦截请求
IOS WKWebview
js调用objc
1.拦截url方式,通过webview:decidePolicyForNavigationAction:decisionHandler实现
2.MessageHandler
objc调用js
1.evaluateJavaScript:completionHandler
通过NSURLProtocol拦截请求
jsbridge和webviewjavascriptbridge本质上就是拦截url方式来实现的。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:225421次
积分:5343
积分:5343
排名:第5389名
原创:307篇
转载:104篇
评论:27条
(20)(11)(10)(40)(70)(61)(57)(68)(47)(26)(1)
(window.slotbydup = window.slotbydup || []).push({
id: '4740887',
container: s,
size: '250,250',
display: 'inlay-fix'}

我要回帖

更多关于 兼容ios和安卓 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信