native.js是什麼且如何使用

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

  1. function judgePlatform(){  
  2.     switch ( plus.os.name ) {  
  3.         case "Android":  
  4.         // Android平臺: plus.android.*  
  5.         break;  
  6.         case "iOS":  
  7.         // iOS平臺: plus.ios.*  
  8.         break;  
  9.         default:  
  10.         // 其它平臺  
  11.         break;  
  12.     }  
  13. }  

 

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

 
  1. Interface ClassObject {  
  2.     function Object plusGetAttribute( String name );  
  3.     function void plusSetAttribute( String name, Object value );  
  4. }  

 

2.4.二、獲取類對象
      在iOS平臺咱們能夠經過plus.ios.importClass(name)方法導入類對象,參數name爲類的名稱;在Android平臺咱們能夠經過plus.android.importClass(name)方法導入類對象,其參數name爲類的名稱,必須包含完整的命名空間。ios

示例:web

 
  1. // iOS平臺導入NSNotificationCenter類  
  2. var NSNotificationCenter = plus.ios.importClass("NSNotificationCenter");  
  3.   
  4. // Android平臺導入Intent類  
  5. var Intent = plus.android.importClass("android.content.Intent");  

 

     獲取類對象後,能夠經過類對象「.」操做符獲取類的靜態常量屬性、調用類的靜態方法,類的靜態很是量屬性需經過plusGetAttribute、plusSetAttribute方法操做。objective-c

實例對象

在JavaScript中,全部對象都是Object,爲了操做Native層類的實例對象,在NJS中引入了實例對象(InstanceObject)的概念,用於對Native中的對象進行操做,如操做對象的屬性、調用對象的方法等。其原型以下:數組

 
  1. Interface InstanceObject {  
  2.     function Object plusGetAttribute( String name );  
  3.     function void plusSetAttribute( String name, Object value );  
  4. }  

 

2.4.三、獲取實例對象
有兩種方式獲取類的實例對象,一種是調用Native API返回值獲取,另外一種是經過new操做符來建立導入的類對象的實例,以下:

 
  1. // iOS平臺導入NSDictionary類  
  2. var NSDictionary = plus.ios.importClass("NSDictionary");  
  3. // 建立NSDictionary的實例對象  
  4. var ns = new NSDictionary();  
  5.   
  6. // Android平臺導入Intent類  
  7. var Intent = plus.android.importClass("android.content.Intent");  
  8. // 建立Intent的實例對象  
  9. 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代碼,用於比對參考:

  1. import android.app.AlertDialog;  
  2. //...  
  3. // 建立提示框構造對象,Builder是AlertDialog的內部類。參數this指代Android的主Activity對象,該對象啓動應用時自動生成  
  4. AlertDialog.Builder dlg = new AlertDialog.Builder(this);  
  5. // 設置提示框標題  
  6. dlg.setTitle("自定義標題");  
  7. // 設置提示框內容  
  8. dlg.setMessage("使用NJS的原生彈出框,可自定義彈出框的標題、按鈕");  
  9. // 設置提示框按鈕  
  10. dlg.setPositiveButton("肯定(或者其餘字符)", null);  
  11. // 顯示提示框  
  12. dlg.show();  
  13. //...  

 

Native.js代碼:

  1. /** 
  2.  * 在Android平臺經過NJS顯示系統提示框 
  3.  */  
  4. function njsAlertForAndroid(){  
  5.     // 導入AlertDialog類  
  6.     var AlertDialog = plus.android.importClass("android.app.AlertDialog");  
  7.     // 建立提示框構造對象,構造函數須要提供程序全局環境對象,經過plus.android.runtimeMainActivity()方法獲取  
  8.     var dlg = new AlertDialog.Builder(plus.android.runtimeMainActivity());  
  9.     // 設置提示框標題  
  10.     dlg.setTitle("自定義標題");  
  11.     // 設置提示框內容  
  12.     dlg.setMessage("使用NJS的原生彈出框,可自定義彈出框的標題、按鈕");  
  13.     // 設置提示框按鈕  
  14.     dlg.setPositiveButton("肯定(或者其餘字符)",null);  
  15.     // 顯示提示框  
  16.     dlg.show();  
  17. }  
  18. //...  

 

 

注意:NJS代碼中建立提示框構造對象要求傳入程序全局環境對象,可經過plus.android.runtimeMainActivity()方法獲取應用的主Activity對象,它是Html5+應用運行期自動建立的程序全局環境對象。

Android設備上運行效果圖:
Android Native.js示例運行效果圖
`注意:其實HTML5+規範已經封裝過原生提示框消息API:plus.ui.alert( message, alertCB, title, buttonCapture)。此處NJS的示例僅爲了開發者方便理解,實際使用時調用plus.ui.alert更簡單,性能也更高。**

iOS

如下代碼在iOS平臺展現調用Native API顯示系統提示對話框。
iOS原生Objective-C代碼,用於比對參考:

  1. #import <UIKit/UIKit.h>  
  2. //...  
  3. // 建立UIAlertView類的實例對象  
  4. UIAlertView *view = [UIAlertView alloc];  
  5. // 設置提示對話上的內容  
  6. [view initWithTitle:@"自定義標題" // 提示框標題  
  7.     message:@"使用NJS的原生彈出框,可自定義彈出框的標題、按鈕" // 提示框上顯示的內容  
  8.     delegate:nil // 點擊提示框後的通知代理對象,nil相似js的null,意爲不設置  
  9.     cancelButtonTitle:@"肯定(或者其餘字符)" // 提示框上取消按鈕的文字  
  10.     otherButtonTitles:nil]; // 提示框上其它按鈕的文字,設置爲nil表示不顯示  
  11. // 調用show方法顯示提示對話框,在OC中使用[]語法調用對象的方法  
  12. [view show];  
  13. //...  

 

Native.js代碼:

 
  1. /** 
  2.  * 在iOS平臺經過NJS顯示系統提示框 
  3.  */  
  4. function njsAlertForiOS(){  
  5.     // 導入UIAlertView類  
  6.     var UIAlertView = plus.ios.importClass("UIAlertView");  
  7.     // 建立UIAlertView類的實例對象  
  8.     var view = new UIAlertView();  
  9.     // 設置提示對話上的內容  
  10.     view.initWithTitlemessagedelegatecancelButtonTitleotherButtonTitles("自定義標題" // 提示框標題  
  11.         , "使用NJS的原生彈出框,可自定義彈出框的標題、按鈕" // 提示框上顯示的內容  
  12.         , null // 操做提示框後的通知代理對象,暫不設置  
  13.         , "肯定(或者其餘字符)" // 提示框上取消按鈕的文字  
  14.         , null ); // 提示框上其它按鈕的文字,設置爲null表示不顯示  
  15.     // 調用show方法顯示提示對話框,在JS中使用()語法調用對象的方法  
  16.     view.show();  
  17. }  
  18. //...  

 

 

注意:在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設備上運行效果圖:
iOS Native.js示例運行效果圖
`注意:其實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

相關文章
相關標籤/搜索