hbuilder支持java插件_HBuilder 第三方插件开发
本人最近開發了 HBulider 集成極光推送(JPush)的插件,鑒于 HBuilder 官網上缺少 iOS 的示例 ,而且官網也只給出了 JavaScript 調用 native 代碼的接口,對于 native 調用 JavaScript 并且向 JavaScript 發送 event 事件的方法卻在 native層 進行了封裝。筆者在踩過了一些小坑之后,終于成功的開發了插件,并且 實現了 JavaScript 和 native 的雙向溝通 。特此跟大家分享一下在 HBuilder 插件開發過程中的經驗和關鍵代碼。
JPush 實例展示
實例及功能展示
以上即為根據本文內容開發出的實例
如您需使用極光推送產品請至此 [極光推送官方網站]
新插件配置
配置 manifest.json
首先用源碼的方式打開工程 /Pandora/ 目錄下的 manifest.json ,在 "permissions" 中添加新的插件名稱:
"permissions": {
"Push":{
"description": "極光推送插件"
}
},
配置 feature.plist
在 Xcode 中打開 /PandoraApi.bundle/ 目錄下的 feature.plist ,為插件添加新的 item:
feature.plist
其中需要注意的是:
最頂部的 key 值 Push ,必須跟 manifest.json 中配置的插件名一致
class 的值需要跟 native 代碼中的類名一致,此處為 JPushPlugin
因為本插件拓展自 HBuilder 已經封裝好的 PGPush ,故 baseclass 為父類
通過以上配置,就可以在 JavaScript 中通過 Push --> JPushPlugin 的對應關系,調用 native 代碼了。
JavaScript 調用本地代碼的實現
這部分在 [HBuilder 官網插件開發指導] 中已經給出了較詳細的說明,這里就不再贅述,附上關鍵代碼:
document.addEventListener("plusready", function() {
var _BARCODE = 'Push'; // 插件名稱
var B = window.plus.bridge;
var JPushPlugin = {
callNative : function(fname, args, successCallback) {
var callbackId = this.getCallbackId(successCallback, this.errorCallback);
if (args != null) {
args.unshift(callbackId);
} else {
var args = [callbackId];
}
return B.exec(_BARCODE, fname, args);
},
getCallbackId : function(successCallback) {
var success = typeof successCallback !== 'function' ? null : function(args)
{
successCallback(args);
};
callbackId = B.callbackId(success, this.errorCallback);
return callbackId;
},
errorCallback : function(errorMsg) {
console.log("Javascript callback error: " + errorMsg);
},
jsHello : function(args){
this.callNative("nativeHello", args, null);
},
window.plus.Push = JPushPlugin;
}, true);
其中 callNative 為封裝好用于調用 native 代碼的方法,參數如下:
fname:要調用的 native 的方法名
args:傳給 native 的參數,必須是數組
successCallback:成功回調,null 為沒有
以上代碼最后面的 "jsHello" 方法,即為封裝好的 js 方法,在工程的其他文件里通過
window.plus.Push.jsHello(args);
的方式即可調用本地的 "nativeHello" 方法。
Objective-C 調用 js 的實現
與 Phonegap 的差異
在 HBuilder 官方文檔中并沒有提及 OC 調用 js 的方法,從 OC 中的類名(PGPlugin 等)可以看出,其應該是對 Phonegap 的封裝,但是卻并沒有提供 Phonegap 中直接調用 js 的接口,例如:
NSString *evalString = [NSString stringWithFormat:@"jsFunction(%@)",args];
[self.commandDelegate evalJs:evalString];
也無法向 js 發送 event ,例如:
NSString *evalString = [NSString stringWithFormat:@"cordova.fireDocumentEvent('event_name',%@)",args];
[self.commandDelegate evalJs:evalString];
其中 self 為繼承自 CDVPlugin 的插件類實例。
經過筆者的查找,發現在 HBuilder 提供的 PDRCoreAppFrame(:PDRNView :UIView) 類中,有如下方法可以調用 js 代碼:
/**
@brief 在當前頁面同步執行Javascript
@param js javasrcipt 腳本
@return NSString* 執行結果
*/
- (NSString*)stringByEvaluatingJavaScriptFromString:(NSString*)js;
獲取 PDRCoreAppFrame 對象
其中 PDRCoreAppFrame 為控制 webView 的實例,數量可能為多個,且在視圖層級中的位置不確定,故需要通過遍歷 app 中所有 view ,來找出 PDRCoreAppFrame ,以下是通過 遞歸 找出所有 PDRCoreAppFrame 的方法:
-(NSMutableArray*)searchViews:(NSArray*)views{
NSMutableArray *frames = [NSMutableArray array];
for (UIView *temp in views) {
if ([temp isMemberOfClass:[PDRCoreAppFrame class]]) {
[frames addObject:temp];
}
if ([temp subviews]) {
NSMutableArray *tempArray = [self searchViews:[temp subviews]];
for (UIView *tempView in tempArray) {
if ([tempView isMemberOfClass:[PDRCoreAppFrame class]]) {
[frames addObject:tempView];
}
}
}
}
return frames;
}
其中:
參數 views 為同一層級中的 views
返回值 frames 為從該層級中找到的 PDRCoreAppFrame
調用 js
這樣我們就可以用上述方法獲取到所有的 PDRCoreAppFrame 進而調用 js 代碼了:
-(void)evaluatingJavaScriptFromString:(NSString*)string{
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
NSArray *views = [[[window rootViewController] view] subviews];
//調用上述方法
NSArray *frames = [self searchViews:views];
for (PDRCoreAppFrame *appFrame in frames) {
dispatch_async(dispatch_get_main_queue(), ^{
[appFrame stringByEvaluatingJavaScriptFromString:string];
});
}
}
調用示例:
NSString *evalString = @"alert("make a js call");";
[self evaluatingJavaScriptFromString:evalString];
但是并不建議用這種方式,因為該方法會強制向每個 webView 的頁面都發送一條執行語句,有時會出現并不希望的結果。因此,建議使用下面發送 event 的方式,并在 js 中接收后進行處理。
向 js 發送 event
筆者對上述方法再次進行了封裝:
-(void)fireEvent:(NSString*)event args:(id)args{
NSString *evalString = nil;
NSError *error = nil;
NSString *argsString = nil;
if (args) {
if ([args isKindOfClass:[NSString class]]) {
argsString = args;
}else{
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:args options:0 error:&error];
argsString = [[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding];
if (error) {
NSLog(@"%@",error);
}
}
evalString = [NSString stringWithFormat:@"\
var jpushEvent = document.createEvent('HTMLEvents');\
jpushEvent.initEvent('%@', true, true);\
jpushEvent.eventType = 'message';\
jpushEvent.arguments = '%@';\
document.dispatchEvent(jpushEvent);",event,argsString];
}else{
evalString = [NSString stringWithFormat:@"\
var jpushEvent = document.createEvent('HTMLEvents');\
jpushEvent.initEvent('%@', true, true);\
jpushEvent.eventType = 'message';\
document.dispatchEvent(jpushEvent);",event];
}
//調用上述方法
[self evaluatingJavaScriptFromString:evalString];
}
其中對傳入的 args 進行了簡單的處理。
最后我們通過調用一行代碼即可做到向 js 發送 event :
[self fireEvent:@"event_name" args:args];
js 接收 event 并處理
在上一步中發送了 "event_name" 的事件之后,可以在 html 的 script 中通過以下方式捕獲:
document.addEventListener("event_name", onEventFunc, false);
function onEventFunc(args){
var obj = JSON.parese(args);
window.setTimeout(function(){
alert(obj);
},0);
}
至此,就徹底實現了 Objective-C 向 js 的溝通
* 如您對本文有任何疑問或建議,歡迎交流
版權印為您的作品印上版權
總結
以上是生活随笔為你收集整理的hbuilder支持java插件_HBuilder 第三方插件开发的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php html 伪静态,php 伪静态
- 下一篇: T6企业管理软件 5.1 - 导出单据列