韩雪峰 發表於 2019-10-11 15:20:00

Android H5混合开发(2):自定义Cordova插件

<h2 id="前言">前言</h2>
<p>Cordova虽然定义了很多基础的插件,供H5端使用原生设备的功能。<br>
但是,如果业务相关的功能,需要提供给H5端使用,那么,就需要我们自定义插件了。<br>
<br><br>
这个“自定义”不是指由Android端任意定义,一般需要各端(H5、原生)讨论来决定,如:插件的名称、action等。</p>
<h2 id="模拟需求">模拟需求</h2>
<pre><code>插件信息:
      插件名称:MyPlugin
      插件id: com.test.MyPlugin
      插件版本:1.0.0
      action: aaa

插件交互方式:当h5调用时,原生toast弹出h5传入的数据,并返回响应的结果。
</code></pre>
<h2 id="创建插件">创建插件</h2>
<p>使用上一篇文章的目录(Android H5混合开发(1):构建Cordova 项目)</p>
<ol>
<li>我们在TestCordova目录下,创建存放自定义插件的目录Plugins<br>
<img src="https://upload-images.jianshu.io/upload_images/10170988-98208415c567dc24.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"></li>
<li>打开终端,输入命令,进入Plugins目录<br>
<img src="https://upload-images.jianshu.io/upload_images/10170988-82492caa7b462199.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"></li>
<li>创建插件<br>
按照约定的插件参数,开始创建插件</li>
</ol>
<pre><code>plugman create --name MyPlugin --plugin_id com.test.MyPlugin --plugin_version 1.0.0
</code></pre>
<p>创建成功,如下图所示:<br>
<img src="https://upload-images.jianshu.io/upload_images/10170988-a57f404f79eff343.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"><br>
/src/目前是空目录<br>
4. 查看www/MyPlugin.js文件<br>
<img src="https://upload-images.jianshu.io/upload_images/10170988-eecf7cd91ce2a98d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"><br>
'MyPlugin'指的是Android端实现该插件的.java类名<br>
'coolMethod'指的是action的名称,此处我们需要修改成约定的 ‘aaa’<br>
修改后,如下图:<br>
<img src="https://upload-images.jianshu.io/upload_images/10170988-bbdcceb281bb06d1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"><br>
5. 查看配置文件plugin.xml<br>
<img src="https://upload-images.jianshu.io/upload_images/10170988-9a1f2fc545df2ef4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"><br>
id="com.test.MyPlugin" 是指插件id;<br>
version="1.0.0" 是指插件版本;<br>
<name>MyPlugin</name> 是指插件名称;<br>
&lt;js-module 标签指定公共JavaScript接口的路径;(即描述H5与原生的接口对应关系)<br>
&lt;clobbers 标签指定了H5端调用插件时的对象,字符串可简化,此处我们改成“xyz”(真实项目中,此文本应根据约定,去定义,此处为了突出演示,所以定义成 xyz)<br>
<img src="https://upload-images.jianshu.io/upload_images/10170988-6c806d5d5c0161c2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"><br>
6. 根据配置文件,生成java代码<br>
使用终端,输入命令,进入MyPlugin目录</p>
<pre><code>cd MyPlugin
</code></pre>
<p>使用终端,输入命令,生成java代码</p>
<pre><code>plugman platform add --platform_name android
</code></pre>
<p><img src="https://upload-images.jianshu.io/upload_images/10170988-7312753e1ec96e5c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"></p>
<p><img src="https://upload-images.jianshu.io/upload_images/10170988-ecf8871b22a9b4d6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"></p>
<p>查看默认的模板脚本(具体实现,后续介绍),如下图:<br>
<img src="https://upload-images.jianshu.io/upload_images/10170988-c94fe02405bde258.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"></p>
<ol start="7">
<li>build 插件<br>
通过终端,输入命令,会创建package.json文件</li>
</ol>
<pre><code>npm init
</code></pre>
<p>根据需要,终端中填写package.json的相关属性。<br>
因为,此Demo只是演示,所以没有填写属性,全部直接点击了回车(即:默认值)。<br>
<img src="https://upload-images.jianshu.io/upload_images/10170988-86f0dc914d7cdd37.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"><br>
创建的package.json文件,如下图所示:<br>
<img src="https://upload-images.jianshu.io/upload_images/10170988-1e2d7a51358ef157.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"><br>
<img src="https://upload-images.jianshu.io/upload_images/10170988-5f8ea0cd98222630.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"><br>
<img src="https://upload-images.jianshu.io/upload_images/10170988-0d7c3080c098c21d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"></p>
<p>至此,插件创建完成。</p>
<h2 id="将插件导入cordova工程的安卓项目中">将插件导入Cordova工程的安卓项目中</h2>
<p>1.通过终端,执行命令,进入cordova工程目录/TestPlugin/myapp/</p>
<pre><code>cd cordova项目目录路径
</code></pre>
<p>2.通过终端,执行命令,将插件加入到各平台的项目中</p>
<pre><code>cordova plugin add 插件的本地路径
</code></pre>
<p><img src="https://upload-images.jianshu.io/upload_images/10170988-b9c8f9dc4e9784af.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"></p>
<p>问题原因:gradle版本权限的问题<br>
解决办法:设置gradle权限<br>
终端命令:chmod +x platforms/android/gradlew<br>
<img src="https://upload-images.jianshu.io/upload_images/10170988-221d547a7c7fa869.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"></p>
<ol start="3">
<li>使用AndroidStuido打开安卓项目,目录:/myapp/platforms/android/<br>
<img src="https://upload-images.jianshu.io/upload_images/10170988-93ba4d397a257ed6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"><br>
经过了cordova plugin add命令,我们可以看到,在/assets/www下面,已经包含了我们导入的插件信息。<br>
3.1 cordova_plugins.js 的module.exports(数组) 描述了插件列表的信息(用到的插件都需要在module.exports数组里面配置):<br>
<img src="https://upload-images.jianshu.io/upload_images/10170988-777af91d58e867eb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"><br>
3.2 Myplugin.js描述了单个插件的具体信息(代码没什么变化,其实就是直接拷贝过来的):<br>
<img src="https://upload-images.jianshu.io/upload_images/10170988-f951aace61639a66.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"><br>
3.3 /res/xml/config.xml 也导入了该插件的相关信息:<br>
<img src="https://upload-images.jianshu.io/upload_images/10170988-453b45faf14d65c4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"><br>
3.4 /src/下自动导入了Java模板代码MyPlugin.java:<br>
<img src="https://upload-images.jianshu.io/upload_images/10170988-58c51799904f1ece.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"></li>
<li>安卓端插件功能开发<br>
其实,也就是在MyPlugin.java类中按照需求实现相关的功能:</li>
</ol>
<pre><code>import android.widget.Toast;

import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CallbackContext;

import org.json.JSONArray;
import org.json.JSONException;

public class MyPlugin extends CordovaPlugin {

    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
      if (action.equals("aaa")) {
            String message = args.getString(0);
            this.aaa(message, callbackContext);
            return true;
      }
      return false;
    }

    private void aaa(String message, CallbackContext callbackContext) {
      //弹框
      Toast.makeText(cordova.getActivity(),"aaa",Toast.LENGTH_LONG).show();
      //h5端传给我什么参数,此处再传回去
      if (message != null &amp;&amp; message.length() &gt; 0) {
            callbackContext.success(message);
      } else {
            callbackContext.error("Expected one non-empty string argument.");
      }
    }
}
</code></pre>
<p>5.H5端开发测试页面,然后同步(或拷贝)给安卓项目使用<br>
直白点,就是H5端做好开发,将WWW目录的内容同步给我们的/assets/www/即可。但是,此处只是个简单的Demo,所以没必要麻烦H5端了,咱们自己写代码实现吧:<br>
5.1首先打开assets/www/index.html文件,删掉多余的注释<br>
<img src="https://upload-images.jianshu.io/upload_images/10170988-85fd61322b7048a2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"><br>
5.2注释掉标签中的第一个<br>
5.3中加入一个button,设置点击事件<br>
5.4编写javascript,h5端调用我们自定义插件的方式:xyz.aaa(...)<br>
<br><br>
index.html完整代码:</p>
<pre><code>&lt;!DOCTYPE html&gt;
&lt;html&gt;
    &lt;head&gt;
      &lt;!--&lt;meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:;"&gt;
      --&gt;&lt;meta name="format-detection" content="telephone=no"&gt;
      &lt;meta name="msapplication-tap-highlight" content="no"&gt;
      &lt;meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width"&gt;
      &lt;link rel="stylesheet" type="text/css" href="css/index.css"&gt;
      &lt;title&gt;Hello World&lt;/title&gt;
    &lt;/head&gt;
    &lt;body&gt;
      &lt;div class="app"&gt;
            &lt;h1&gt;Apache Cordova&lt;/h1&gt;
            &lt;div id="deviceready" class="blink"&gt;
                &lt;p class="event listening"&gt;Connecting to Device&lt;/p&gt;
                &lt;p class="event received"&gt;Device is Ready&lt;/p&gt;
            &lt;/div&gt;
            &lt;br&gt;&lt;br&gt;&lt;br&gt;
            &lt;button onclick="test()"&gt;aaa click&lt;/button&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;
      &lt;/div&gt;
      &lt;script type="text/javascript" src="cordova.js"&gt;&lt;/script&gt;
      &lt;script type="text/javascript" src="js/index.js"&gt;&lt;/script&gt;
      &lt;script &gt;

    function test(){
      xyz.aaa("AAA",function(msg){
            alert('原生返回了:'+msg);
      },function(e){
            alert(e);
      })
    }
&lt;/script&gt;
    &lt;/body&gt;
&lt;/html&gt;

</code></pre>
<ol start="6">
<li>连上手机,运行androidstudio,点击【aaa click】按钮,如下图:<br>
<img src="https://upload-images.jianshu.io/upload_images/10170988-d45ae80b2b66487d.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"></li>
</ol>
<h2 id="总结">总结</h2>
<p>本篇文章,主要演示了cordova插件的自定义过程和插件的使用,比较基础,没有涉及过多复杂的事情,如果有不明白的地方,建议去官网多查查资料。<br>
https://cordova.apache.org/docs/en/latest/<br>
需要使用Cordova童鞋,最好先跟着例子多练习几遍,熟能生巧。<br>
后续会介绍更多的Cordova使用技巧。<br>
本次Demo的源码下载地址:https://pan.baidu.com/s/1YmMw2zO7goF7MDViB1wZ2Q</p>
<hr>
<p>Android H5混合开发(1):构建Cordova 项目<br>
https://www.cnblogs.com/qixingchao/p/11654454.html</p>
<p>Android H5混合开发(2):自定义Cordova插件<br>
https://www.cnblogs.com/qixingchao/p/11652418.html</p>
<p>Android H5混合开发(3):原生Android项目里嵌入Cordova<br>
https://www.cnblogs.com/qixingchao/p/11652424.html</p>
<p>Android H5混合开发(4):构建Cordova Jar包<br>
https://www.cnblogs.com/qixingchao/p/11652431.html</p>
<p>Android H5混合开发(5):封装Cordova View, 让Fragment、弹框、Activity自由使用Cordova<br>
https://www.cnblogs.com/qixingchao/p/11652438.html</p><br><br>
来源:https://www.cnblogs.com/qixingchao/p/11652418.html
頁: [1]
查看完整版本: Android H5混合开发(2):自定义Cordova插件