Hybridge
又一个用于混合应用的javascript / 移动原生简单桥接器,双向...
索引
为什么选择它?
在开发混合应用时,您肯定需要访问不同的原生功能和资源。市面上有许多桥接解决方案。Hybridge 尝试让原生(iOS & Android)和 JavaScript 世界之间的通信和数据处理变得简单,避免过多的开销。
安装
Hybridge遵循语义化版本控制。在boilerplate
目录中,您可以找到如何在不同的平台中运行的示例。
JavaScript
从v1.2.0版本开始,hybridge
在bower中可用。Bower将自行安装hybridge
及其所有依赖。
bower install --save hybridge
将其添加到您的HTML中
<script type="text/javascript" src="bower_components/hybridge/js/hybridge.js"></script>
您可以手动下载javascript js/hybridge.js并使用传统方式。
Hybridge以AMD/Vanilla JavaScript方式同时工作。对于Vanilla JavaScript,它可在window.Hybridge
变量中找到。您还需要JQuery(版本1.8.3或更高),因为在这个部分使用到了Deferred对象。
Android
您可以构建自己的Hybridge,但可以从样板代码中的最新版本开始,版本号为hybridge.jar。
iOS
将其添加到您的Podfile
中,并运行$ pod install
。
pod 'Hybridge'
如果您尚未安装或集成CocoaPods到项目中,您可以在这里学习如何做到这一点:这里。
使用
原生和 JavaScript 之间有两种通信方式。在 Android 和 iOS 中实现了不同的方式,但两种环境中 JavaScript 部分是相同的。
-
Hybridge 使用 操作 作为原生任务,这些任务在从 JavaScript 请求并发送 JSON 数据以及接收 JSON 响应时执行。
-
原生 Hybridge 部分可以在需要时触发 原生事件 并将附件的 JSON 数据发送到 JavaScript。
JavaScript
在您的 AMD 代码中以模块的形式加载 hybridge.js
。最简单的安装方法
<script src="js/require.js"></script>
<script>
require.config({
baseUrl: 'js/lib',
paths: {
jquery: 'bower_components/jquery/dist/jquery',
hybridge: 'bower_components/hybridge/js/hybridge'
}
});
require(['hybridge'], function (Hybridge) {
Hybridge.init({
'environment' : 'ios'
}
});
});
</script>
在原生中定义的假设性 downloadAction
可以轻松地从 JavaScript 调用。
Hybridge.send({'action' : 'download', 'url' : 'http://...'})
您将在回调函数中对处理进行响应时收到一个 JavaScript Promise。
Hybridge.send({'action' : 'gpsposition'}).done(updateMap);
Android
-
编译源文件并将
hybridge.jar
与项目依赖一起复制。或者,您可以设置 Hybridge 项目作为 Android 库依赖项。 -
通过实现
JsAction
接口作为Enum
来创建自己的 操作。Hybridge 将在每个 操作 中分别处理这些操作,并以异步任务的形式进行。
public enum JsActionImpl implements JsAction {
DOWNLOAD(DownloadTask.class),
GPSPOSITION(GPSPositionTask.class),
CALLCONTACT(CallContactTask.class);
private Class task;
private JsActionImpl(Class task) {
this.setTask(task);
}
@Override
public Class getTask() {
return task;
}
@Override
public void setTask(Class task) {
this.task = task;
}
...
}
public class DownloadTask extends AsyncTask<Object, Void, JSONObject> {
private JsPromptResult result;
private Context context;
private HybridgeBroadcaster hybridge;
public DownloadTask(Context context) {
this.context = context;
}
@Override
protected JSONObject doInBackground(Object... params) {
JSONObject json = (JSONObject) params[0];
result = (JsPromptResult) params[1];
hybridge = (HybridgeBroadcaster) params[2];
// Process download
...
return json;
}
...
}
- 使用
HybridgeWebChromeClient
和HybridgeWebViewClient
在 WebView 中,将操作实现的枚举值作为构造函数参数。
webView.setWebViewClient(new HybridgeWebViewClient(JsActionImpl.values()));
webView.setWebChromeClient(new HybridgeWebChromeClient(JsActionImpl.values()));
- 在 WebView 碎片中实现
Observable
,并订阅它,以便在接收来自HybridgeBroadcaster
的事件时通知 JavaScript。
HybridgeBroadcaster.getInstance(mWebView).addObserver(this);
...
@Override
public void update(Observable observable, Object data) {
JSONObject json = (JSONObject) data;
if (json.has(HybridgeConst.EVENT_NAME)) {
try {
HybridgeBroadcaster.getInstance(mWebView).fireJavascriptEvent(mWebView, (Event) json.get(HybridgeConst.EVENT_NAME), json);
} catch (JSONException e) {
Log.e(mTag, "Problem with JSON object " + e.getMessage());
}
} else {
HybridgeBroadcaster.getInstance(mWebView).fireMessage(mWebView, json);
}
}
iOS
创建一个 WebView 控制器
Hybridge 提供了 HYBWebViewController
,这是一个便利的视图控制器,它同时托管一个网页视图和与之通信的中介对象。建议用户扩展 HYBWebViewController
并指定任何受支持的桥梁操作。
#import <Hybridge/Hybridge.h>
@interface MyWebViewController : HYBWebViewController
@end
...
- (NSArray *)bridgeActions:(HYBBridge *)bridge {
return @[@"some_action", @"some_other_action"];
}
有两种不同的方式来处理桥梁操作
- 重写
-bridgeDidReceiveAction:data:
- (NSDictionary *)bridgeDidReceiveAction:(NSString *)action data:(NSDictionary *)data {
if ([action isEqualToString:@"some_action"]) {
// Handle 'some_action'
} else if ([action isEqualToString:@"some_other_action"]) {
// Handle 'some_other_action'
}
// Return a JSON dictionary or `nil`
return nil;
}
- 为每个支持的操作实现一个具有特殊签名的封装方法。桥梁将会寻找具有以下签名的封装方法:
- (NSDictionary *)handle<YourActionInCamelCase>WithData:(NSDictionary *)data
- (NSDictionary *)handleSomeActionWithData:(NSDictionary *)data {
// Handle 'some_action'
return @{ @"foo": @"bar" };
}
- (NSDictionary *)handleSomeOtherActionWithData:(NSDictionary *)data {
// Handle 'some_other_action'
return nil;
}
请注意方法签名的 驼峰格式。如果你的操作名是 some_action
,则该方法签名变为 SomeAction
。
样板程序
开始使用 Hybridge 的最快途径是使用样板程序。
首先,你需要一份运行在你的开发环境中的本地服务器以加载初始测试文件。既有支持 iOS 和 Android 的环境项目,也有一个名为 hybridge.html
的测试 HTML 文件,你可以将其放在本地服务器的根目录下,连同 hybridge.js
文件一起作为你应用程序开发的开端。你只需要将那些文件放入你的本地网页文档的根目录下,并根据需要修改它们,同时更改原始的本地测试路径(http://127.0.0.1/hybridge.html
)到另一个 URL。这样就可以非常简单地将之前的网页应用程序迁移为混合应用程序。不过,还需要一个 HTTP 路径,因为目前 Hybridge 不支持本地 HTML 文件的加载。
本地事件
你可以通过触发 Hybridge 中定义的任何 events
来与 Android/iOS 中的 JavaScript 通信。
- ready:Hybridge 初始化。
- pause:移动应用进入后台。
- resume:移动应用进入前台。
- message:需要时发送任意数据。
Android
使用HybridgeBroadcaster实例在JavaScript中触发事件
HybridgeBroadcaster.getInstance(mWebView).fireJavascriptEvent(webView, Event.READY, jsonData);
iOS
Hybridge提供了一个UIWebView
类别,该类别提供了一种便利方法,用于在JavaScript方面触发事件。
[self.webView hyb_fireEvent:HYBEventMessage data:@{ @"foo": @"bar" }];
Javascript
订阅您的JavaScript在ready
事件到本地事件,以便在回调函数中处理接收到的数据
function processData (event) {
var data = ev.data;
...
}
Hybridge.addListener(Hybridge.events.ready, function () {
Hybridge.addListener(Hybridge.events.message, processData);
...
});
请务必删除您的处理程序,以避免内存泄漏
Hybridge.removeListener(Hybridge.events.message, processData);
Javascript API
一个好的起点可能是简单地查看hybridge.js中的代码,但让我们列举出从Hybridge JavaScript对象中可用的方法和属性
方法
-
init(configuration:Object) 提供初始化配置
-
环境 (ios|android : String),必选,因为您想要与本地端通信。
-
日志记录器 (Function),可选的日志记录对象处理器,否则使用
window.console
对象作为标准输出。 -
调试 (boolean),激活调试(网页端)模式,更多信息请参阅下文。
-
模拟响应 (Object),为调试模式提供可选的模拟对象。
-
isNative() 如果环境值正确分配,则返回true。
-
isEnabled() 如果Hybridge已经初始化(本地化和JavaScript部分)或开启了
调试
模式,则返回true。 -
addListener(hybridgeEvent:Event, callback:Function) 将一个
Hybridge事件
订阅到一个回调处理程序。 -
removeListener(hybridgeEvent:Event, callback:Function) 从回调处理器中取消订阅
Hybridge 事件
。 -
isEventImplemented(hybridgeEvent:String) 如果当前原生版本的 Hybridge 实现了此事件,则返回 true。
-
isActionImplemented(hybridgeEvent:String) 如果当前原生版本的 Hybridge 实现了此动作,则返回 true。
-
send(data:Object[, fallback:Function]) 提供了从 JavaScript 通信到原生端的方式。执行已实现的本地任务需要要求一个
action
参数。返回一个包含从原生端或自定义错误返回的数据的 JQuery Promise。您可以添加第二个函数参数fallback
,以防出现错误,同时您想提供额外的用户反馈以及更新您的用户界面。 -
ready(callback:Function) 当 Hybridge 已启用时执行回调函数的功能。如果在调用时 Hybridge 已启用,则立即执行回调。与
addListener('ready', handler)
事件订阅的主要区别在于,当发生订阅且 Hybridge 已启用时,事件处理器永远不会执行。
属性
- errors Hybridge 返回的自定义错误容器对象
- NO_NATIVE: 环境不是移动原生(iOS 或 Android)。
- NO_NATIVE_ENABLE: 原生环境不支持原生 Hybridge。
- NO_FALLBACK: 调用 hybridge 缺少回退函数。
- ACTION_NOT_IMPLEMENTED: hybridge 的动作未在本地实现。
- WRONG_PARAMS: hybridge 的调用没有所需参数(动作)。
- EVENT_NOT_IMPLEMENTED: hybridge 事件未在本地实现。
- DEBUG_MODE: Hybridge 在调试模式,请求的功能不可用。
- MALFORMED_JSON: Hybridge 尝试解析或字符串化格式不正确的 JSON(调试模式)。
- events 可用 原生事件 的容器对象。
- version 当前 JavaScript Hybridge 的版本。
调试
Hybridge 提供了一种简单的方法来模拟原生移动响应,您可以在进行 UI 开发部分的工作时使用。给定一个 downloadStatus
动作,它可以在 Hybridge 初始化时进行模拟。
Hybridge.init({
'environment': 'android',
'logger': CustomLoger,
'debug': true,
'mockResponses': {
'downloadStatus': {
'downloadedPercentage': 50
}
}
});
当页面调用 downloadStatus
动作时,将显示一个提示窗口,其中包含 JSON 模拟数据。您可以按需修改它以进行您的 UI 测试。
自定义错误
在典型场景中,如果网页和本地原生组件可以是不同版本,您可以通过处理自定义错误来解决它
Hybridge.send({
'action' : 'download',
'url' : url
})
.done(updateUIfunction)
.fail(function (e) {
if (e.error && e.error === Hybridge.errors.ACTION_NOT_IMPLEMENTED) {
// Advise user to update native applicacion to the newest version
...
}
});
Demos
即将推出...
License
版权所有 (c) 2013 Telefonica Digital。许可协议为MIT许可证。MIT许可证简单易懂,对tdigital-hybridge项目几乎没有任何限制。
只要版权头信息保留不变,您可以在任何其他项目中(即使是商业项目)免费使用tdigital-hybridge项目。