uni-app是一个开源前端框架,是用vue.js开发的,可以实现跨平台的开发。地址:https://github.com/dcloudio/uni-app 而Native.js是使用uni-app开发时可以用到的一种开发技术,以下介绍摘自《5+ App开发Native.js入门指南》:http://ask.dcloud.net.cn/article/88 本文只是对上面这个文章的一些摘抄和提炼,方便Android开发者参考。
Native.js技术,简称NJS,是一种将手机操作系统的原生对象转义,映射为JS对象,在JS里编写原生代码的技术。 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应用。再次强调,Native.js不是一个js库,不需要下载引入到页面的script中,也不像nodejs那样有单独的运行环境,Native.js的运行环境是集成在5+runtime里的,使用HBuilder打包的app或流应用都可以直接使用Native.js。
简言之,Native.js可以实现用js语法来调用Android或者ios的功能,以实现一处开发,多处运行的目的。使用HBuilder这个开发工具完成功能开发后,需要把打包数据放入Android项目或者ios项目里,然后就可以编译得到Android或者ios安装包。 HBuilder工具下载地址:https://www.dcloud.io/hbuilderx.html
本文主要介绍Native.js如何配合Android开发。
以一个简单的例子说明一下Native.js的使用: 如果Android 项目里有个工具类ToastUtil.java是用来管理Toast的,其中有个静态方法用来显示Toast:
package com.example.demo; public static void show(Context ctx, CharSequence msg, int duration) { XXX }在Android项目里,如果是这样用的:
ToastUtil.show(MainActivity.this, "提醒一下", Toast.LENGTH_LONG);对应到了native.js里,写法就是这样:
var ToastUtil = plus.android.importClass("com.example.demo.ToastUtil"); var Toast = plus.android.importClass("android.widget.Toast"); ToastUtil.show(plus.android.runtimeMainActivity(), "提醒一下", Toast.LENGTH_LONG);其中plus.android.importClass是用来导入类的,然后由于ToastUtil类的show方法是静态方法,Toast类的LENGTH_LONG是静态常量,所以都是可以用类后面跟点号来使用的。plus.android.runtimeMainActivity()是用来获取当前的activity。详细语法后面会讲,这里先大概有个印象。
当然上面的写法如果运行在ios平台上就会出错了,所以在native.js里,得针对不同操作系统做判断:
switch ( plus.os.name ) { case "Android": // Android平台: plus.android.* var ToastUtil = plus.android.importClass("com.example.demo.ToastUtil"); var Toast = plus.android.importClass("android.widget.Toast"); ToastUtil.show(plus.android.runtimeMainActivity(), "提醒一下", Toast.LENGTH_LONG); break; case "iOS": // iOS平台: plus.ios.* break; default: // 其它平台 break; }如果还有兴趣继续看下去的话,接下来就是详细讲解了。
以一个更全面的例子来讲解,下面是一个测试类:
package io.dcloud; // 定义类NjsHello public class NjsHello { // 静态常量 public static final int CTYPE = 1; // 静态变量 public static int count; // 成员常量 public final String BIRTHDAY = "2013-01-13"; // 成员变量 String name; //定义属性name NjsHelloEvent observer; public void updateName( String newname ) { //定义方法updateName name = newname; } public void setEventObserver( NjsHelloEvent newobserver ) { observer = newobserver; } public void test() { //定义方法test System.out.printf( "My name is: %s", name ); observer.onEventInvoked( name ); } public static void testCount() { System.out.printf( "Static count is:%d", count ); } static{ // 初始化类的静态变量 NjsHello.count = 0; } }这是上面的代码中用到的接口类:
package io.dcloud; // 定义接口NjsHelloEvent public interface NjsHelloEvent { public void onEventInvoked( String name ); }下面看如何在native.js中使用这个测试类:
· 导入类后获取类的静态常量属性
// 导入测试类NjsHello var NjsHello = plus.android.importClass("io.dcloud.NjsHello"); // 获取类的静态常量属性 var type = NjsHello.CTYPE;· 导入类后调用类的静态方法
// 导入测试类NjsHello var NjsHello = plus.android.importClass("io.dcloud.NjsHello"); // 调用类的静态方法 NjsHello.testCount();· 导入类后获取类的静态变量值
// 导入测试类NjsHello var NjsHello = plus.android.importClass("io.dcloud.NjsHello"); // 获取类的静态变量 var count = NjsHello.plusGetAttribute( "count" ); console.log( "NjsHello Static's value: "+count ); // 输出“NjsHello Static's value: 0”· 导入类后设置类的静态属性值
// 导入测试类NjsHello var NjsHello = plus.android.importClass("io.dcloud.NjsHello"); // 设置类的静态属性值 NjsHello.plusSetAttribute( "count", 2 ); console.log( "NjsHello Static's value: "+NjsHello.plusGetAttribute( "count" ) ); // 输出“NjsHello Static's value: 2”· 导入类创建实例对象,调用对象的方法
// 导入测试类NjsHello var NjsHello = plus.android.importClass("io.dcloud.NjsHello"); // 创建NjsHello的实例对象 var hello = new NjsHello(); // 调用对象的方法 hello.updateName( "Tester" ); // ...· 导入类创建实例对象,获取对象的常量属性
// 导入测试类NjsHello var NjsHello = plus.android.importClass("io.dcloud.NjsHello"); // 创建NjsHello的实例对象 var hello = new NjsHello(); // 访问对象的常量属性 var birthday = hello.BIRTHDAY; console.log( "NjsHello Object Final's value: "+birthday ); // 输出“NjsHello Object Final's value: 2013-01-13” // ...· 导入类创建实例对象,获取对象的属性值
// 导入测试类NjsHello var NjsHello = plus.android.importClass("io.dcloud.NjsHello"); // 创建对象的实例 var hello = new NjsHello(); hello.updateName( "Tester" ); // 获取其name属性值 var name = hello.plusGetAttribute( "name" ); console.log( "NjsHello Object's name: "+name ); // 输出“NjsHello Object's name: Tester” // ...· 导入类创建实例对象,设置对象的属性值
// 导入测试类NjsHello var NjsHello = plus.android.importClass("NjsHello"); // 创建对象的实例 var hello = new NjsHello(); // 设置其name属性值 hello.plusSetAttribute( "name", "Tester" ); console.log( "NjsHello Object's name: "+hello.plusGetAttribute("name") ); // 输出“NjsHello Object's name: Tester” // ...· 实现接口,并触发接口中函数的运行
// 导入测试类NjsHello var NjsHello = plus.android.importClass("io.dcloud.NjsHello"); // 实现接口“NjsHelloEvent”对象 var hevent = plus.android.implements( "io.dcloud.NjsHelloEvent", { "onEventInvoked":function( name ){ console.log( "Invoked Object’s name: "+name ); // 输出“Invoked Object’s name: Tester” } } ); // 创建对象的实例 var hello = new NjsHello(); // 调用updateName方法 hello.updateName( "Tester" ); // 设置监听对象 hello.setEventObserver( hevent ); // 调用test方法,触发代理事件 hello.test(); // 触发上面定义的匿名函数运行 // ...有前述的常用API,已经可以完成各项业务开发。此处补充的高级API,是在熟悉NJS后,为了提升性能而使用的API。高级API无法直接用“.”操作符使用原生对象的方法,在debug时也无法watch原生对象,但高级API性能高于常规API。 虽然导入类对象(plus.android.importClass和plus.ios.importClass)后,可以方便的通过“.”操作符来访问对象的常量、调用对象的方法,但导入类对象也需要消耗较多的系统资源,所以在实际开发时应该尽可能的减少导入类对象,以提高程序效率。
如果我们不导入类对象则无法通过new操作符实例化类对象,这时可通过plus.ios.newObject()、plus.android.newObject()方法来创建实例对象。
注意:由于没有导入类对象,所以通过此方法创建的实例对象无法通过“.”操作符直接调用对象的方法,而必须使用plus.android.invoke方法来调用。
· 不导入类创建实例对象
// 不调用plus.android.importClass("io.dcloud.NjsHello")导入类NjsHello // 创建对象的实例 var hello = plus.android.newObject( "io.dcloud.NjsHello" ); // ...· 不导入类对象获取类的静态常量属性
// 不调用plus.android.importClass("io.dcloud.NjsHello")导入类NjsHello // 访问类的静态常量属性 var type = plus.android.getAttribute( "io.dcloud.NjsHello", "CTYPE" ); console.log( "NjsHello Final's value: "+type ); // 输出“NjsHello Final's value: 1” // ...· 不导入类对象,创建实例对象,并获取其name属性值
// 不调用plus.android.importClass("io.dcloud.NjsHello")导入类NjsHello // 创建对象的实例 var hello = plus.android.newObject( "io.dcloud.NjsHello" ); // 获取其name属性值 var name = plus.android.getAttribute( hello, "name" ); console.log( "NjsHello Object's name: "+name ); // 输出“NjsHello Object's name: Tester” // ...· 不导入类对象设置类的静态属性值
// 不调用plus.android.importClass("io.dcloud.NjsHello")导入类NjsHello // 设置类的静态属性值 plus.android.setAttribute( "io.dcloud.NjsHello", "count", 2 ); console.log( "NjsHello Static's value: "+plus.android.getAttribute("io.dcloud.NjsHello","count") ); // 输出“NjsHello Static's value: 2” // ...· 不导入类对象,创建实例对象,并设置其name属性值
// 不调用plus.android.importClass("io.dcloud.NjsHello")导入类NjsHello // 创建对象的实例 var hello = plus.android.newObject( "io.dcloud.NjsHello" ); // 设置其name属性值 plus.android.setAttribute( hello, "name", "Tester" ); console.log( "NjsHello Object's name: "+hello.plusGetAttribute("name") ); // 输出“NjsHello Object's name: Tester” // ...· 不导入类对象,调用类的静态方法
// 不调用plus.android.importClass("io.dcloud.NjsHello")导入类NjsHello // 调用类的静态方法 plus.android.invoke( "io.dcloud.NjsHello", "testCount" ); // ...· 不导入类对象,创建实例对象,并调用其updateNmae方法
在这里插入代码片// 不调用plus.android.importClass("io.dcloud.NjsHello")导入类NjsHello // 创建对象的实例 var hello = plus.android.newObject( "io.dcloud.NjsHello" ); // 调用updateName方法 plus.android.invoke( hello, "updateName", "Tester" ); console.log( "NjsHello Object's name: "+hello.getAttribute("name") ); // 输出“NjsHello Object's name: Tester” // ...关于Native.js调用其它Android系统功能,可以看这里:https://ask.dcloud.net.cn/article/114
本文是从这篇讲解里提炼出来的,如果有问题,可以查看原文: http://ask.dcloud.net.cn/article/88