native.js是什么且如何使用


native.js是什么且如何使用

一、總結

一句話總結:Native.js技術,簡稱NJS,是一種將手機操作系統的原生對象轉義,映射為JS對象,在JS里編寫原生代碼的技術。Native.js不是一個js庫,不需要下載引入到頁面的script中,也不像nodejs那樣有單獨的運行環境,Native.js的運行環境是集成在5+runtime里的,使用HBuilder打包的app或流應用都可以直接使用Native.js。

 

 

二、Native.js使用入門

1、概述

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技術不能在普通手機瀏覽器里直接運行。

  • 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。

技術要求

   由於NJS是直接調用Native API,需要對Native API有一定了解,知道所需要的功能調用了哪些原生API,能看懂原生代碼並參考原生代碼修改為JS代碼。否則只能直接copy別人寫好的NJS代碼。

2、開始使用

2.1、判斷平台

Native API具有平台依賴性,所以需要通過以下方式判斷當前的運行平台:

  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.2、類型轉換

在NJS中調用Native API或從Native API返回數據到NJS時會自動轉換數據類型。

類型轉換表

類型 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.3、其他轉換

 

  • 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.4、概念

 2.4.1、類對象

由於JavaScript中本身沒有類的概念,為了使用Native API層的類,在NJS中引入了類對象(ClassObject)的概念,用於對Native中的類進行操作,如創建類的實例對象、訪問類的靜態屬性、調用類的靜態方法等。其原型如下:

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

 

2.4.2、獲取類對象
      在iOS平台我們可以通過plus.ios.importClass(name)方法導入類對象,參數name為類的名稱;在Android平台我們可以通過plus.android.importClass(name)方法導入類對象,其參數name為類的名稱,必須包含完整的命名空間。

示例:

 
  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方法操作。

實例對象

在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.3、獲取實例對象
有兩種方式獲取類的實例對象,一種是調用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方法訪問。

     

3、開始寫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

 

三、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

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM