博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
native.js是什么且如何使用
阅读量:6623 次
发布时间:2019-06-25

本文共 12145 字,大约阅读时间需要 40 分钟。

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里编写原生代码的技术。如果说把js扩展到服务器世界,那么Native.js则把js扩展到手机App的原生世界。HTML/JS/Css全部语法只有7万多,而原生语法有几十万,Native.js大幅提升了的能力。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的代码示例,复制粘贴就可以用。

     再次强调,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、类对象

由于中本身没有类的概念,为了使用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、获取类对象

      在平台我们可以通过plus.ios.importClass(name)方法导入类对象,参数name为类的名称;在平台我们可以通过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语法的原因,方法名称中的“:”字符转成NJS对象的方法名称后将会被忽略,因此在NJS中调用的方法名需去掉所有“:”字符。

  • 类的继承

    Objective-C和中类如果存在继承自基类,在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对象,它是+应用运行期自动创建的程序全局环境对象。

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本地分享

直接拨打电话

将程序切换到后台

强制弹出软键盘

获取安卓设备device.uuid

获取内存及CPU信息

开启关闭蓝牙

监听蓝牙开关状态

获取蓝牙设备列表

蓝牙连接票据打印机完整代码

NFC数据读取

截屏

获取MAC地址

获取设备当前网速

打开网络设置

打开各种系统设置界面

获取WIFI列表

调用系统控件播放视频

调用os通讯录选择控件

原生日历提醒插入

调用系统控件裁剪图片

复制内容到系统粘贴板

调用讯飞的文字转语音功能(TTS)

调用其它Activity后通过startActivityForResult获取返回结果

接收系统广播消息,如监听安装卸载apk的事件

判断app是否安装

以监听手机飞行模式开关为例说明如何使用Native.js进行BroadcastReceiver广播

常驻Android通知栏,不用个推实现本地消息推送(Local Notification)

调用原生的socket连接

启动一个原生service

基于native.js的文件系统管理功能实现

打开闪光灯

停止、开启个推推送功能

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); }

感谢分享

利用native.js获取手机gps是否开启

通过native.js设置系统墙纸

监听短信验证码

限制手机录像时间

iOS平台

获取包名

var NSBundle = plus.ios.importClass('NSBundle'); var bundle = NSBundle.mainBundle(); console.log(bundle.bundleIdentifier()); plus.ios.deleteObject(bundle);

获取设备名

测试是否安装某应用

调用iOS打印API

通过native.js登入game center

见Hello H5+里Native.js部分演示及源码。

或在这里搜索“game center”,

设置获取内容到系统粘贴板

打开页面默认弹出键盘

播放提示音

调用ios的文字转语音(TTS)

把base64数据保存为图片

设置webview滑动减速度

var webview = plus.ios.currentWebview(); var scrollView = webview.plusGetAttribute("scrollView"); scrollView.plusSetAttribute("decelerationRate:",0.99);

打开ios的Wifi设置页面

判断是否开启消息通知

检测iOS是否允许使用相机(感谢分享)

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

 

 

 

 
你可能感兴趣的文章
【IOS-COCOS2D-X 游戏开发之二】【必看篇】总结阐述COCOS2D-X与COCOS2D-IPHONE区别;
查看>>
eoLinker-API_Shop_通讯服务类API调用的代码示例合集:短信服务、手机号归属地查询、电信基站查询等...
查看>>
前端面试回忆录 - 滴滴篇 - 凉面
查看>>
jxl导入Excel 切割List 并使用MyBatis批量插入数据库
查看>>
小程序开发总结
查看>>
Tomcat监听器设计思路
查看>>
管理ORACLE实例
查看>>
Confluence 6 MySQL 数据库设置准备
查看>>
Ruby 中 0/0.0 = NaN
查看>>
JEESNS数据库表设计结构
查看>>
JavaScript学习笔记:判断变量是否为undefined,判断变量和函数是否声明
查看>>
局域网访问Apache服务器
查看>>
JavaScript 闭包
查看>>
Spark算子:RDD行动Action操作(3)–aggregate、fold、lookup
查看>>
UILabel总结
查看>>
java获取当前时间前一周、前一月、前一年的时间
查看>>
话说WEB开发之页面重绘和回流
查看>>
using标识使用
查看>>
解决linux下不能上网
查看>>
nginx rewrite伪静态配置参数说明
查看>>