Native.js技术,简称NJS,是一种将手机操作系统的原生对象转义,映射为JS对象,在JS里编写原生代码的技术,由DCloud(数字天堂)公司开发。说人话就是:通过 native.js, 你可以在 html 代码的<script></script>
标签中用 native.js语法直接调用 Android 原生 API。
本次文章主要目的是学习如何利用 Native.js 实现在 HTML 中获取 Android 原生代码的数据,很多人一看到”html与Android数据交互”可能都会想到WebView,在 webview 中使用 jsBridge,是的,我一开始也是这个念头,遗憾的是我当时的项目使用的是 DCloud 的 MUI 框架,所有页面都是由 html+js 组成,几乎没怎么用到 Android 原生控件,所以这个方法行不通,当然现在的hybrid 模式的框架,原理都是封装一层 JSBridge ,通过 JSBridge 去访问原生的硬件功能。
本次项目是从AndroidStudio 创建 Hybrid App工程项目基础修改而来,把AndroidStudio 创建 Hybrid App工程没有用到的 MainActivity 加上(如果被删掉了就再创建一个),大体思路就是在 MainActivity 数据持久化,然后在 html 页面通过 native.js 获取,MainActivity修改代码如下:
public class MainActivity extends ListActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//存放一些数据到SharePreferences
initData();
setListAdapter(new MyListAdapter());
getListView().setTextFilterEnabled(true);
}
private void initData() {
//Log.d(TAG, "initData: hello");
SharedPreferences sharedPreferences = getSharedPreferences("data", Context.MODE_PRIVATE);
SharedPreferences.Editor edit = sharedPreferences.edit();
edit.putString("data1","aaaa").putString("data2","bbbb").apply();
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Intent intent = new Intent(this,activityInfos[position].clazz);
startActivity(intent);
}
ActiviyInfo[] activityInfos = new ActiviyInfo[]{
new ActiviyInfo("SDK_APP",SDK_Runtime.class),
new ActiviyInfo("SDK_WEBAPP",SDK_WebApp.class)
};
class ActiviyInfo{
String title;
Class<? extends Activity> clazz;
public ActiviyInfo(String title, Class<? extends Activity> clazz) {
this.title = title;
this.clazz = clazz;
}
}
class MyListAdapter extends BaseAdapter {
@Override
public int getCount() {
return activityInfos.length;
}
@Override
public Object getItem(int position) {
return activityInfos[position];
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView tv = new TextView(parent.getContext());
tv.setHeight(100);
tv.setGravity(Gravity.CENTER);
tv.setText(activityInfos[position].title);
convertView = tv;
return convertView;
}
}
}
复制代码
上面代码我直接用了 Android-SDK 中 HBuilder-Integrate 中的代码,MainActivity 中的SDK_Runtime 和 SDK_Webapp 类 直接从 HBuilder-Integrate/src下拷贝过来的
当然,在AndroidManifest.xml中要配置 activity(这里贴出主要代码)
<application
android:name="io.dcloud.application.DCloudApplication"
android:allowClearUserData="true"
android:icon="@drawable/icon"
android:label="@string/app_name"
android:largeHeap="true">
<activity
android:name="io.dcloud.PandoraEntry"
android:configChanges="orientation|keyboardHidden|keyboard|navigation"
android:hardwareAccelerated="true"
android:label="@string/app_name"
android:launchMode="singleTask"
android:screenOrientation="user"
android:theme="@style/TranslucentTheme"
android:windowSoftInputMode="adjustResize">
</activity>
<activity android:name=".MainActivity"
android:theme="@style/AppTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="io.dcloud.PandoraEntryActivity"
android:configChanges="orientation|keyboardHidden|screenSize|keyboard|navigation|mcc|mnc|fontScale"
android:hardwareAccelerated="true"
android:label="5+Debug"
android:launchMode="singleTask"
android:screenOrientation="user"
android:theme="@style/DCloudTheme"
android:windowSoftInputMode="adjustResize">
</activity>
<activity
android:name=".SDK_Runtime"
android:configChanges="orientation|keyboardHidden|screenSize|keyboard|navigation|mcc|mnc|fontScale"
android:screenOrientation="sensor">
</activity>
<activity
android:name=".SDK_WebApp"
android:configChanges="orientation|keyboardHidden|screenSize|keyboard|navigation|mcc|mnc|fontScale"
android:screenOrientation="user"
android:theme="@android:style/Theme.Translucent">
</activity>
<service
android:name="io.dcloud.common.adapter.io.MiniServerService"
android:exported="true" />
</application>
复制代码
运行程序后界面是这样子
接下来就是在html中取值了
- 首先找到调用native.js的那部分html页面
-
根据 DCloud 提供的如何使用 native.js 语法来写
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"/> <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/> <title>Hello H5+</title> <link rel="stylesheet" href="../css/common.css"> <script type="text/javascript" src="../js/common.js"></script> <script type="text/javascript"> function njsAlertForAndroid(){ <!--全局环境--> var mainActivity = plus.android.runtimeMainActivity(); <!--导包--> var Toast = plus.android.importClass("android.widget.Toast"); var Context = plus.android.importClass("android.content.Context"); var SharedPreferences = plus.android.importClass("android.content.SharedPreferences"); var sp = mainActivity.getSharedPreferences("data",Context.MODE_PRIVATE); <!--var a = sp.getString("a","");-->//这种写法不行 <!--var b = sp.getString("b","");--> var value1 = plus.android.invoke(sp,"getString","data1",""); var value2 = plus.android.invoke(sp,"getString","data2",""); var toast = Toast.makeText(mainActivity,"data1:"+value1+"\n"+"data2:"+value2,Toast.LENGTH_SHORT); toast.show(); } </script> </head> <body> <header id="header"> <div class="nvbt iback" onclick="back(true);"></div> <div class="nvtt">Native.JS</div> <div class="nvbt idoc" onclick="openDoc('Native.JS Document','/doc/native.js.html')"></div> </header> <div id="dcontent" class="dcontent"> <br/> <ul class="dlist"> <li class="ditem" onclick="njsAlertForAndroid()">native.js调用Android原生代码数据</li> <li class="ditem" onclick="clicked('njs_efficient.html')">native.js高级API</li> </ul> <br/> <div class="button button-waring" onclick="plus.runtime.openURL('http://ask.dcloud.net.cn/article/114');">更多示例... </div> </div> <div id="output"> Native.JS一种把操作系统的原生对象转义,映射为JS对象,在JS里编写原生代码的技术。可通过plus.android.*和plus.ios.*提供的API分别调用Android和iOS平台的Native API。 </div> </body> <script type="text/javascript" src="../js/immersed.js"></script> </html> 复制代码
注意,限于篇幅,我把njs.html的一些无关代码代码简化了
- 运行程序,可以看到,值已经成功取出来了
更多关于使用 native.js的例子可以查看这里: Native.js示例汇总
hogenlaw.com ,欢迎来踩!