native.js是什麼且如何使用
1、總結
一句話總結:Native.js技術,簡稱NJS,是一種將手機操做系統的原生對象轉義,映射爲JS對象,在JS裏編寫原生代碼的技術。Native.js不是一個js庫,不須要下載引入到頁面的script中,也不像nodejs那樣有單獨的運行環境,Native.js的運行環境是集成在5+runtime裏的,使用HBuilder打包的app或流應用均可以直接使用Native.js。
2、Native.js使用入門
一、概述
Native.js技術,簡稱NJS,是一種將手機操做系統的原生對象轉義,映射爲JS對象,在JS裏編寫原生代碼的技術。若是說Node.js把js擴展到服務器世界,那麼Native.js則把js擴展到手機App的原生世界。HTML/JS/Css所有語法只有7萬多,而原生語法有幾十萬,Native.js大幅提高了HTML5的能力。NJS突破了瀏覽器的功能限制,也再也不須要像Hybrid那樣由原生語言開發插件才能補足瀏覽器欠缺的功能。NJS編寫的代碼,最終須要在HBuilder裏打包發行爲App安裝包,或者在支持Native.js技術的瀏覽器裏運行。目前Native.js技術不能在普通手機瀏覽器裏直接運行。javascript
- NJS大幅擴展了HTML5的能力範圍,本來只有原生或Hybrid App的原生插件才能實現的功能現在可使用JS實現。
- NJS大幅提高了App開發效率,將iOS、Android、Web的3個工程師組隊才能完成的App,變爲1個web工程師就搞定。
- NJS再也不須要配置原生開發和編譯環境,調試、打包均在HBuilder裏進行。沒有mac和xcode同樣能夠開發iOS應用。
- 若是不熟悉原生API也不要緊,咱們彙總了不少NJS的代碼示例,複製粘貼就能夠用。http://ask.dcloud.net.cn/article/114
再次強調,Native.js不是一個js庫,不須要下載引入到頁面的script中,也不像nodejs那樣有單獨的運行環境,Native.js的運行環境是集成在5+runtime裏的,使用HBuilder打包的app或流應用均可以直接使用Native.js。html
技術要求
因爲NJS是直接調用Native API,須要對Native API有必定了解,知道所須要的功能調用了哪些原生API,能看懂原生代碼並參考原生代碼修改成JS代碼。不然只能直接copy別人寫好的NJS代碼。html5
二、開始使用
2.一、判斷平臺
Native API具備平臺依賴性,因此須要經過如下方式判斷當前的運行平臺:java
- function judgePlatform(){
- switch ( plus.os.name ) {
- case "Android":
- // Android平臺: plus.android.*
- break;
- case "iOS":
- // iOS平臺: plus.ios.*
- break;
- default:
- // 其它平臺
- break;
- }
- }
2.二、類型轉換
在NJS中調用Native API或從Native API返回數據到NJS時會自動轉換數據類型。node
類型轉換表
類型 | Objective-C | Java | JavaScript |
---|---|---|---|
基本數據 | byte/short/int/long/float/double/... | byte/short/int/long/float/double/... | Number |
字符 | char | char | String |
字符串 | NSString/@"" | String/"" | String |
數組 | @[1,2,3]/NSArray | new XXX[] | InstanceObject |
類 | @interface | class | ClassObject |
對象(實例) | * | * | InstanceObject |
空對象 | nil | null | null |
其它 | Protocol | Interface | Object(JSON) |
2.三、其餘轉換
- Android原生應用的主Activity對象 轉爲plus.android.runtimeMainActivity()
Android的主Activity對象是啓動應用時自動建立的,不是代碼建立,此時經過plus.android.runtimeMainActivity()方法獲取該Activity對象 - Objective-C方法冒號剔除
[pos setPositionX:(int)x Y:(int)y;] 轉爲 pos.setPositionXY(x,y);
OC語法中方法的定義格式爲:
「(返回值類型) 函數名: (參數1類型) 形參1 參數2名稱: (參數2類型) 形參2」
方法的完整名稱爲: 「函數名:參數2名稱:」。
如:「(void)setPositionX:(int)x Y:(int)y;」,方法的完整名稱爲「setPositionX:Y:」,調用時語法爲:「[pos setPositionX:x Y:y];」。
在JS語法中函數名稱不能包含「:」字符,因此OC對象的方法名映射成NJS對象方法名時將其中的「:」字符自動刪除,上面方法名映射爲「setPositionXY」,在NJS調用的語法爲:「pos.setPositionXY(x,y);」。 - 文件路徑轉換
Web開發裏使用的image/1.png是該web工程的相對路徑,而原生API中常常須要使用絕對路徑,好比/sdcard/apptest/image/1.png,此時使用這個擴展方法來完成轉換:plus.io.convertLocalFileSystemURL("image/1.png")
2.四、概念
2.4.一、類對象
因爲JavaScript中自己沒有類的概念,爲了使用Native API層的類,在NJS中引入了類對象(ClassObject)的概念,用於對Native中的類進行操做,如建立類的實例對象、訪問類的靜態屬性、調用類的靜態方法等。其原型以下:android
- Interface ClassObject {
- function Object plusGetAttribute( String name );
- function void plusSetAttribute( String name, Object value );
- }
2.4.二、獲取類對象
在iOS平臺咱們能夠經過plus.ios.importClass(name)方法導入類對象,參數name爲類的名稱;在Android平臺咱們能夠經過plus.android.importClass(name)方法導入類對象,其參數name爲類的名稱,必須包含完整的命名空間。ios
示例:web
- // iOS平臺導入NSNotificationCenter類
- var NSNotificationCenter = plus.ios.importClass("NSNotificationCenter");
- // Android平臺導入Intent類
- var Intent = plus.android.importClass("android.content.Intent");
獲取類對象後,能夠經過類對象「.」操做符獲取類的靜態常量屬性、調用類的靜態方法,類的靜態很是量屬性需經過plusGetAttribute、plusSetAttribute方法操做。objective-c
實例對象
在JavaScript中,全部對象都是Object,爲了操做Native層類的實例對象,在NJS中引入了實例對象(InstanceObject)的概念,用於對Native中的對象進行操做,如操做對象的屬性、調用對象的方法等。其原型以下:數組
- Interface InstanceObject {
- function Object plusGetAttribute( String name );
- function void plusSetAttribute( String name, Object value );
- }
2.4.三、獲取實例對象
有兩種方式獲取類的實例對象,一種是調用Native API返回值獲取,另外一種是經過new操做符來建立導入的類對象的實例,以下:
- // iOS平臺導入NSDictionary類
- var NSDictionary = plus.ios.importClass("NSDictionary");
- // 建立NSDictionary的實例對象
- var ns = new NSDictionary();
- // Android平臺導入Intent類
- var Intent = plus.android.importClass("android.content.Intent");
- // 建立Intent的實例對象
- var intent = new Intent();
獲取實例對象後,能夠經過實例對象「.」操做符獲取對象的常量屬性、調用對象的成員方法,實例對象的很是量屬性則需經過plusGetAttribute、plusSetAttribute方法操做。
操做對象的屬性方法
-
常量屬性
獲取對象後就能夠經過「.」操做符獲取對象的常量屬性,若是是類對象則獲取的是類的靜態常量屬性,若是是實例對象則獲取的是對象的成員常量屬性。 -
很是量屬性
若是Native層對象的屬性值在原生環境下被更改,此時使用「.」操做符獲取到對應NJS對象的屬性值就可能不是實時的屬性值,而是該Native層對象被映射爲NJS對象那一刻的屬性值。
爲獲取獲取Native層對象的實時屬性值,需調用NJS對象的plusGetAttribute(name)方法,參數name爲屬性的名稱,返回值爲屬性的值。調用NJS對象的plusSetAttribute(name,value)方法設置Native層對象的很是量屬性值,參數name爲屬性的名稱,value爲要設置新的屬性值。注意:使用plusGetAttribute(name)方法也能夠獲取Native層對象的常量屬性值,但不如直接使用「.」操做符來獲取性能高。
-
方法
獲取對象後能夠經過「.」操做符直接調用Native層方法,若是是類對象調用的是Native層類的靜態方法,若是是實例對象調用的是Native層對象的成員方法。注意:在iOS平臺因爲JS語法的緣由,Objective-C方法名稱中的「:」字符轉成NJS對象的方法名稱後將會被忽略,所以在NJS中調用的方法名需去掉全部「:」字符。
-
類的繼承
Objective-C和Java中類若是存在繼承自基類,在NJS中對應的對象會根據繼承關係遞歸將全部基類的公有方法一一換成NJS對象的方法,全部基類的公有屬性也能夠經過其plusGetAttribute、plusSetAttribute方法訪問。
三、開始寫NJS
使用NJS調用Native API很是簡單,基本步驟以下:
a. 導入要使用到的類;
b. 建立類的實例對象(或者調用類的靜態方法建立);
c. 調用實例對象的方法;
如下例子使用NJS調用iOS和Android的原生彈出提示框(相似但不一樣於js的alert)。
Android
如下代碼在Android平臺展現調用Native API顯示系統提示框。
首先是Android原生 Java代碼,用於比對參考:
- import android.app.AlertDialog;
- //...
- // 建立提示框構造對象,Builder是AlertDialog的內部類。參數this指代Android的主Activity對象,該對象啓動應用時自動生成
- AlertDialog.Builder dlg = new AlertDialog.Builder(this);
- // 設置提示框標題
- dlg.setTitle("自定義標題");
- // 設置提示框內容
- dlg.setMessage("使用NJS的原生彈出框,可自定義彈出框的標題、按鈕");
- // 設置提示框按鈕
- dlg.setPositiveButton("肯定(或者其餘字符)", null);
- // 顯示提示框
- dlg.show();
- //...
Native.js代碼:
- /**
- * 在Android平臺經過NJS顯示系統提示框
- */
- function njsAlertForAndroid(){
- // 導入AlertDialog類
- var AlertDialog = plus.android.importClass("android.app.AlertDialog");
- // 建立提示框構造對象,構造函數須要提供程序全局環境對象,經過plus.android.runtimeMainActivity()方法獲取
- var dlg = new AlertDialog.Builder(plus.android.runtimeMainActivity());
- // 設置提示框標題
- dlg.setTitle("自定義標題");
- // 設置提示框內容
- dlg.setMessage("使用NJS的原生彈出框,可自定義彈出框的標題、按鈕");
- // 設置提示框按鈕
- dlg.setPositiveButton("肯定(或者其餘字符)",null);
- // 顯示提示框
- dlg.show();
- }
- //...
注意:NJS代碼中建立提示框構造對象要求傳入程序全局環境對象,可經過plus.android.runtimeMainActivity()方法獲取應用的主Activity對象,它是Html5+應用運行期自動建立的程序全局環境對象。
Android設備上運行效果圖:
`注意:其實HTML5+規範已經封裝過原生提示框消息API:plus.ui.alert( message, alertCB, title, buttonCapture)。此處NJS的示例僅爲了開發者方便理解,實際使用時調用plus.ui.alert更簡單,性能也更高。**
iOS
如下代碼在iOS平臺展現調用Native API顯示系統提示對話框。
iOS原生Objective-C代碼,用於比對參考:
- #import <UIKit/UIKit.h>
- //...
- // 建立UIAlertView類的實例對象
- UIAlertView *view = [UIAlertView alloc];
- // 設置提示對話上的內容
- [view initWithTitle:@"自定義標題" // 提示框標題
- message:@"使用NJS的原生彈出框,可自定義彈出框的標題、按鈕" // 提示框上顯示的內容
- delegate:nil // 點擊提示框後的通知代理對象,nil相似js的null,意爲不設置
- cancelButtonTitle:@"肯定(或者其餘字符)" // 提示框上取消按鈕的文字
- otherButtonTitles:nil]; // 提示框上其它按鈕的文字,設置爲nil表示不顯示
- // 調用show方法顯示提示對話框,在OC中使用[]語法調用對象的方法
- [view show];
- //...
Native.js代碼:
- /**
- * 在iOS平臺經過NJS顯示系統提示框
- */
- function njsAlertForiOS(){
- // 導入UIAlertView類
- var UIAlertView = plus.ios.importClass("UIAlertView");
- // 建立UIAlertView類的實例對象
- var view = new UIAlertView();
- // 設置提示對話上的內容
- view.initWithTitlemessagedelegatecancelButtonTitleotherButtonTitles("自定義標題" // 提示框標題
- , "使用NJS的原生彈出框,可自定義彈出框的標題、按鈕" // 提示框上顯示的內容
- , null // 操做提示框後的通知代理對象,暫不設置
- , "肯定(或者其餘字符)" // 提示框上取消按鈕的文字
- , null ); // 提示框上其它按鈕的文字,設置爲null表示不顯示
- // 調用show方法顯示提示對話框,在JS中使用()語法調用對象的方法
- view.show();
- }
- //...
注意:在OC語法中方法的定義格式爲:
「(返回值類型) 函數名: (參數1類型) 形參1 參數2名稱: (參數2類型) 形參2」
方法的完整名稱爲: 「函數名:參數2名稱:」。
如:「(void)setPositionX:(int)x Y:(int)y;」,方法的完整名稱爲「setPositionX:Y:」
調用時語法爲:「[pos setPositionX:x Y:y];」。
在JS語法中函數名稱不能包含「:」字符,因此OC對象的方法名映射成NJS對象方法名時將其中的「:」字符自動刪除,上面方法名映射爲「setPositionXY」,在NJS調用的語法爲:「pos.setPositionXY(x,y);」。
iOS設備上運行效果圖:
`注意:其實HTML5+規範已經封裝過原生提示框消息API:plus.ui.alert( message, alertCB, title, buttonCapture)。此處NJS的示例僅爲了開發者方便理解,實際使用時調用plus.ui.alert更簡單、性能也更高。
在HBuilder自帶的Hello H5+模板應用中「Native.JS」(plus/njs.html)頁面有完整的源代碼,可真機運行查看效果。
------------------
轉載 :http://blog.csdn.net/qq_27626333/article/details/51853039
3、Native.js示例彙總
Native.js雖然強大和開放,但不少web開發者由於不熟悉原生API而難以獨立完成。
這篇帖子的目的就是彙總各類寫好的NJS代碼,方便web開發者。
衆人拾柴火焰高,有能力的開發者多多提交NJS代碼,你們都會給你點讚的,咱們也會爲每位共享NJS代碼的朋友送上200積分。
Android平臺
調用Android本地分享
http://ask.dcloud.net.cn/article/134
直接撥打電話
http://ask.dcloud.net.cn/question/4035
將程序切換到後臺
http://ask.dcloud.net.cn/question/2484
強制彈出軟鍵盤
http://ask.dcloud.net.cn/question/2324
獲取安卓設備device.uuid
http://ask.dcloud.net.cn/question/3510
獲取內存及CPU信息
http://ask.dcloud.net.cn/question/2202
開啓關閉藍牙
http://ask.dcloud.net.cn/question/4720
監聽藍牙開關狀態
http://ask.dcloud.net.cn/article/274
獲取藍牙設備列表
http://ask.dcloud.net.cn/question/8265
藍牙鏈接票據打印機完整代碼
http://ask.dcloud.net.cn/article/643
NFC數據讀取
http://ask.dcloud.net.cn/question/6726
截屏
http://ask.dcloud.net.cn/question/5344
獲取MAC地址
http://ask.dcloud.net.cn/question/1511
獲取設備當前網速
http://ask.dcloud.net.cn/article/773
打開網絡設置
http://ask.dcloud.net.cn/question/1475
打開各類系統設置界面
http://ask.dcloud.net.cn/question/14732
獲取WIFI列表
http://ask.dcloud.net.cn/question/12113
調用系統控件播放視頻
http://ask.dcloud.net.cn/question/614
調用os通信錄選擇控件
http://ask.dcloud.net.cn/question/5783
原生日曆提醒插入
http://ask.dcloud.net.cn/article/215
調用系統控件裁剪圖片
http://ask.dcloud.net.cn/question/8314
複製內容到系統粘貼板
http://ask.dcloud.net.cn/question/2034
調用訊飛的文字轉語音功能(TTS)
http://ask.dcloud.net.cn/question/6473
調用其它Activity後經過startActivityForResult獲取返回結果
http://ask.dcloud.net.cn/question/5783
接收系統廣播消息,如監聽安裝卸載apk的事件
http://ask.dcloud.net.cn/article/222
判斷app是否安裝
http://ask.dcloud.net.cn/question/7604
以監聽手機飛行模式開關爲例說明如何使用Native.js進行BroadcastReceiver廣播
http://ask.dcloud.net.cn/question/7661
常駐Android通知欄,不用個推實現本地消息推送(Local Notification)
http://ask.dcloud.net.cn/question/2464
調用原生的socket鏈接
http://ask.dcloud.net.cn/question/60
啓動一個原生service
http://ask.dcloud.net.cn/question/433
基於native.js的文件系統管理功能實現
http://ask.dcloud.net.cn/article/809
打開閃光燈
http://ask.dcloud.net.cn/question/19379
中止、開啓個推推送功能
var pushManager = plus.android.importClass("com.igexin.sdk.PushManager"); var context = plus.android.runtimeMainActivity(); function enable() { pushManager.getInstance().turnOnPush(context); } function disable() { pushManager.getInstance().turnOffPush(context); }
感謝yeahcheung分享
利用native.js獲取手機gps是否開啓
http://ask.dcloud.net.cn/question/11890
經過native.js設置系統牆紙
http://ask.dcloud.net.cn/article/651
監聽短信驗證碼
http://ask.dcloud.net.cn/article/676
限制手機錄像時間
http://ask.dcloud.net.cn/question/45756
iOS平臺
獲取包名
var NSBundle = plus.ios.importClass('NSBundle'); var bundle = NSBundle.mainBundle(); console.log(bundle.bundleIdentifier()); plus.ios.deleteObject(bundle);
獲取設備名
http://ask.dcloud.net.cn/question/14691
測試是否安裝某應用
http://ask.dcloud.net.cn/question/14430
調用iOS打印API
http://ask.dcloud.net.cn/question/4226
經過native.js登入game center
見Hello H5+裏Native.js部分演示及源碼。
或在這裏搜索「game center」,http://ask.dcloud.net.cn/docs/#http://ask.dcloud.net.cn/article/88
設置獲取內容到系統粘貼板
http://ask.dcloud.net.cn/question/3720
打開頁面默認彈出鍵盤
http://ask.dcloud.net.cn/question/2324
播放提示音
http://ask.dcloud.net.cn/question/3962
調用ios的文字轉語音(TTS)
http://ask.dcloud.net.cn/question/4175
把base64數據保存爲圖片
http://ask.dcloud.net.cn/question/6190
設置webview滑動減速度
var webview = plus.ios.currentWebview(); var scrollView = webview.plusGetAttribute("scrollView"); scrollView.plusSetAttribute("decelerationRate:",0.99);
打開ios的Wifi設置頁面
http://ask.dcloud.net.cn/question/7797
判斷是否開啓消息通知
http://ask.dcloud.net.cn/question/4497
檢測iOS是否容許使用相機(感謝小鬧分享)
http://ask.dcloud.net.cn/article/188
ios獲取系統的時區id
var NSTimeZone = plus.ios.importClass("NSTimeZone"); var sys = NSTimeZone.systemTimeZone(); console.log(sys.plusGetAttribute("name"));
狀態欄顯示網絡請求雪花
var UIApplication = plus.ios.import("UIApplication"); var sharedApplication = UIApplication.sharedApplication(); sharedApplication.setNetworkActivityIndicatorVisible(true); plus.ios.deleteObject(sharedApplication);
獲取GPS受權狀態
var CLLocationManager = plus.ios.import("CLLocationManager"); var authorizationStatus = CLLocationManager.authorizationStatus(); switch(authorizationStatus) { case 0: /// User has not yet made a choice with regards to this application break; case 1: // This application is not authorized to use location services. Due // to active restrictions on location services, the user cannot change // this status, and may not have personally denied authorization break; case 2: // User has explicitly denied authorization for this application, or // location services are disabled in Settings. break; case 3: // User has granted authorization to use their location at any time, // including monitoring for regions, visits, or significant location changes. break; case 4: // User has granted authorization to use their location only when your app // is visible to them (it will be made visible to them if you continue to // receive location updates while in the background). Authorization to use // launch APIs has not been granted. break; case 5: // This value is deprecated, but was equivalent to the new -Always value. break; defalut: break; }
獲取手機存儲空間
var BundleClass = plus.ios.importClass("NSBundle"); var BundleObj = BundleClass.mainBundle(); var filenamagerobj = plus.ios.newObject("NSFileManager"); var FileAttr = plus.ios.invoke(filenamagerobj,"attributesOfFileSystemForPath:error:",BundleObj.bundlePath(),null); // NSFileSystemFreeSize 參數獲取剩餘空間 // NSFileSystemSize 獲取手機總存儲空間 var freeSpace = plus.ios.invoke(FileAttr,"objectForKey:","NSFileSystemFreeSize"); var numberFormatterObj = plus.ios.newObject("NSNumberFormatter"); var FreeSpaceStr = plus.ios.invoke(numberFormatterObj,"stringFromNumber:",freeSpace); var freeSpace = FreeSpaceStr / 1024/1024/1024;
打開/關閉手機的閃光燈
function turnonLight(isOn) { if(plus.os.name == "iOS") { var avcaptClass = plus.ios.importClass("AVCaptureDevice"); if(avcaptClass) { var device = avcaptClass.defaultDeviceWithMediaType("vide"); plus.ios.invoke(device, "lockForConfiguration:", null); if(isOn) { plus.ios.invoke(device, "setTorchMode:", 1); plus.ios.invoke(device, "setFlashMode:", 1); } else { plus.ios.invoke(device, "setTorchMode:", 0); plus.ios.invoke(device, "setFlashMode:", 0); } plus.ios.invoke(device, "unlockForConfiguration"); } } };
顯示應用內的ViewController
// NewViewController爲應用內建立的原生的ViewController類名,所調用頁面的內容須要在原生代碼中完成 var newVCobj = plus.ios.newObject("NewViewController"); var UIApplicationClass = plus.ios.importClass("UIApplication"); var UIAppObj = UIApplicationClass.sharedApplication(); var del = plus.ios.invoke(UIAppObj,"delegate"); // 若是當前應用delegate對象包含UIWindow對象而且變量名命名爲「window」能夠這麼寫, // 不然須要根據實際代碼狀況修改 // 應用的delegate對象也能夠添加一個返回UIViewController的方法 var appWindowObj = plus.ios.invoke(del,"window"); var appRootController = plus.ios.invoke(appWindowObj,"rootViewController"); plus.ios.invoke(appRootController,"presentViewController:animated:completion:",newVCobj,"YES",null);
參考:Native.js示例彙總 - DCloud問答http://ask.dcloud.net.cn/article/114