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 ,歡迎來踩!