利用 Native.js 实现 Android 与 HTML 数据的交互

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 ,欢迎来踩!

转载于:https://juejin.im/post/5a45d503f265da431a43829d

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值