zoukankan      html  css  js  c++  java
  • [Cordova] Plugin开发入门

    [Cordova] Plugin开发入门

    Overview

    Cordova的设计概念,是在APP上透过Web控件来呈现Web页面,让Web开发人员可以操作熟悉的语言、工具来开发APP。使用Web页面来呈现功能内容,的确可以满足大部分的功能需求,但是因为APP的使用情景毕竟有别于Web,某些APP的功能需求像是:拨打电话、扫描条形码...等等,无法单纯使用Web开发技术就能实现。

    为了让Web页面能够满足更多的APP功能需求,Cordova提供了Plugin机制,让Web页面能够挂载并调用Native开发技术所开发的功能模块。当开发人员遇到Web开发技术无法实现的功能需求时,可以到Cordova官网(https://cordova.apache.org/plugins/),下载并使用官方提供的各种通用Plugin功能模块。而就算遇到了特殊的功能需求,Cordova也提供了方法,让开发人员可以自行开发专属于自己的客制Plugin功能模块。

    本篇文章介绍如何建立一个Cordova Plugin功能模块,让开发人员能够使用Native开发技术,在Cordova里开发Plugin功能模块给Web页面使用,让Web页面能够满足更多的APP功能需求。主要是为自己留个纪录,也希望能帮助到有需要的开发人员。

    Overview02

    Cordova Plugin Metadata

    Cordova Plugin功能模块会以文件夹的形式,存放于本机文件系统或是远程Git服务器。使用Visual Studio开发Cordova项目的时候,只要输入档案路径或是服务器路径,就可以自动完成挂载Plugin功能模块的动作。

    CordovaPluginMetadata01

    挂载Plugin功能模块的时候,Visual Studio会读取文件夹下的「plugin.xml」。这个XML档案中定义了Plugin功能模块的相关设定项目,这些设定项目里用于描述Plugin功能模块的,主要项目为:

    • id : Plugin标识符
    • version : Plugin版本
    • name : Plugin名称
    • description : Plugin描述
    • license : Plugin授权模式
    • js-module : 各个JavaScript模块的设定项目
    • platform : 各个执行平台的设定项目
    <?xml version="1.0" encoding="UTF-8"?>
    <plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"        
            id="clk-cordova-sample" 
            version="1.0.0">
    
        <!-- metadata -->
        <name>CLK Cordova Sample</name>
        <description>CLK Cordova Sample的说明</description>
        <license>Apache 2.0</license>
    
        <!-- javascript -->
        <js-module>...</js-module>
        <js-module>...</js-module>
    
        <!-- android -->
        <platform name="android">...</platform>
    
        <!-- ios -->
        <platform name="ios">...</platform>
    
    </plugin>
    

    Android Platform Plugin

    platform metadata

    Cordova在编译Android Platform Plugin的时候,会先建立编译用的Android项目,并且读取plugin.xml里被标注为android的platform设定区块,做为编译时期的编译参数。

    <!-- android -->
    <platform name="android">        
        <!-- config -->
        <config-file target="res/xml/config.xml" parent="/*">
            <feature name="NotificationService">
                <param name="android-package" value="com.clk.cordova.sample.NotificationService"/>
            </feature>
        </config-file>        
        <!-- source -->
        <source-file src="src/android/NotificationService.java" target-dir="src/com/clk/cordova/sample/" />
    </platform>
    

    source-file

    当Cordova读取到Android platform的设定区块的source-file设定区块时,会将每一个source-file设定区块里src所指定的档案,复制到Android项目里target-dir所指定文件夹,用以进行后续的编译工作。在本篇的范例里,source-file设定区块所代表的意义是:将Plugin里src/android/NotificationService.java的这个档案,复制到Android项目的src/com/clk/cordova/sample/文件夹里面来进行编译。

    <!-- source -->
    <source-file src="src/android/NotificationService.java" target-dir="src/com/clk/cordova/sample/" />
    

    AndroidPlatformPlugin01

    config-file

    Android platform的设定区块的config-file设定区块比较特别,这个设定区块是用来,定义提供给Web页面调用的类别。在这其中feature name代表的是这个Plugin提供给Web页面使用的类别别名,而param value里定义的则是实际提供服务的Native类别名称,剩余其他设定参数则是编译所需的固定参数。在本篇范例里,config-file设定区块所代表的意义是:Web页面可以使用NotificationService这个类别别名,来调用Android项目里面的com.clk.cordova.sample.NotificationService这个Native类别。

    <!-- config -->
    <config-file target="res/xml/config.xml" parent="/*">
        <feature name="NotificationService">
            <param name="android-package" value="com.clk.cordova.sample.NotificationService"/>
        </feature>
    </config-file>        
    

    native code

    Android platform plugin里,使用Native技术所开发的Native类别,必须先继承org.apache.cordova.CordovaPlugin这个类别,再经由source-file设定加入项目编译,后续才可以透过config-file的定义提供Web页面调用。而Web页面调用Native类别时,Cordova会执行Native类别的execute方法,并且提供下列内容:

    • action : 方法名称。
      • 因为只有execute一个进入点,所以使用action来分发方法,让一个Class能够提供更多方法。
    • args : 方法参数。
      • 对应方法名称的参数内容、为JSONArray格式。
    • callbackContext : 方法回呼。
      • 方法成功时呼叫callbackContext.success回传成功结果、方法失败时呼叫callbackContext.error回传错误讯息。
    • return : 是否接受调用。
      • 方法成功时回传true、方法失败时回传false。
    package com.clk.cordova.sample;
    
    import org.apache.cordova.*;
    import org.json.*;
    import android.widget.Toast; 
    
    public class NotificationService extends CordovaPlugin {
    
        // methods
        public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
    
            // show
            if(action.equals("show")) {
    
                // arguments
                String message = args.getString(0); 
    
                // execute
                Toast.makeText(this.cordova.getActivity(), message, Toast.LENGTH_LONG).show();
    
                // return
                return true;
            }
    
            // default
            return false;       
        }
    }
    

    cordova.exec

    完成上述Android Platform Plugin的相关开发工作之后,在挂载这个Cordova Plugin的Android执行平台里,Web页面就可以使用统一的cordova.exec方法,来调用Native开发的类别。这个cordova.exec接口会执行Native类别的execute方法,并且带入下列内容:

    1. success : 方法成功时的Callback函式。
    2. error:方法失败时的Callback函式。
    3. feature:config-file设定区块所定义的类别别名。
    4. action:Native类别提供的方法名称。
    5. args:Native类别提供的方法参数。
    cordova.exec(success, error, feature, action, args);
    

    iOS Platform Plugin

    platform metadata

    Cordova在编译iOS Platform Plugin的时候,会先建立编译用的iOS项目,并且读取plugin.xml里被标注为ios的platform设定区块,做为编译时期的编译参数。

    <!-- ios -->
    <platform name="ios">
        <!-- config -->
        <config-file target="config.xml" parent="/*">
            <feature name="NotificationService">
                <param name="ios-package" value="CLKNotificationService"/>
            </feature>
        </config-file>
        <!-- source -->
        <header-file src="src/ios/CLKNotificationService.h" />
        <source-file src="src/ios/CLKNotificationService.m" />
    </platform>
    

    source-file

    当Cordova读取到iOS platform的设定区块的source-file设定区块时,会将每一个source-file设定区块里src所指定的档案,复制到iOS项目的Plugin文件夹,用以进行后续的编译工作。在本篇的范例里,source-file设定区块所代表的意义是:将Plugin里src/ios/CLKNotificationService.h跟CLKNotificationService.m的这两个档案,复制到iOS项目的Plugin文件夹里面来进行编译。

    <!-- source -->
    <header-file src="src/ios/CLKNotificationService.h" />
    <source-file src="src/ios/CLKNotificationService.m" />
    

    iOSPlatformPlugin01

    config-file

    iOS platform的设定区块的config-file设定区块比较特别,这个设定区块是用来,定义提供给Web页面调用的类别。在这其中feature name代表的是这个Plugin提供给Web页面使用的类别别名,而param value里定义的则是实际提供服务的Native类别名称,剩余其他设定参数则是编译所需的固定参数。在本篇范例里,config-file设定区块所代表的意义是:Web页面可以使用NotificationService这个类别别名,来调用iOS项目里面的CLKNotificationService这个Native类别。

    <!-- config -->
    <config-file target="config.xml" parent="/*">
        <feature name="NotificationService">
            <param name="ios-package" value="CLKNotificationService"/>
        </feature>
    </config-file>
    

    native code

    iOS platform plugin里,使用Native技术所开发的Native类别,必须先继承CDVPlugin这个类别,再经由source-file设定加入项目编译,后续才可以透过config-file的定义提供Web页面调用。而Web页面调用Native类别时,Cordova会依照Web页面所提供的action参数,来执行Native类别里同名的方法,并且提供下列内容:

    • CDVInvokedUrlCommand : 执行指令

      • @property (nonatomic, readonly) NSString* callbackId; : 回呼编号
      • (id)argumentAtIndex:(NSUInteger)index; : 取得输入参数
    • CDVPluginResult : 执行结果

      • @property (nonatomic, strong, readonly) NSNumber* status; : 执行结果(Ex:成功、失败...)
      • @property (nonatomic, strong, readonly) id message; : 回传参数(Ex:String、Bool...)
    • CDVPlugin(self) : 继承的CDVPlugin

      • @property (nonatomic, weak) id commandDelegate; : 回传执行结果物及回呼编号
    // CLKNotificationService.h
    #import <Foundation/Foundation.h>
    #import <Cordova/CDVPlugin.h>
    
    @interface CLKNotificationService : CDVPlugin
    
    // methods
    -(void)show:(CDVInvokedUrlCommand*)command;
    
    @end
    
    // CLKNotificationService.m
    #import "CLKNotificationService.h"
    
    @implementation CLKNotificationService
    
    // methods
    - (void)show:(CDVInvokedUrlCommand*)command
    {
        // arguments
        NSString* message = [command argumentAtIndex:0];
    
        // execute
        [[[UIAlertView alloc] initWithTitle:nil message:message delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
    }
    
    @end
    

    cordova.exec

    完成上述iOS Platform Plugin的相关开发工作之后,在挂载这个Cordova Plugin的iOS执行平台里,Web页面就可以使用统一的cordova.exec方法,来调用Native开发的类别。这个cordova.exec接口会提供action参数,来执行Native类别里同名的方法,并且带入下列内容:

    1. success : 方法成功时的Callback函式。
    2. error:方法失败时的Callback函式。
    3. feature:config-file设定区块所定义的类别别名。
    4. action:Native类别提供的方法名称。
    5. args:Native类别提供的方法参数。
    cordova.exec(success, error, feature, action, args);
    

    JavaScript Module Plugin

    Cordova提供统一的cordova.exec方法,让Web页面调用Native开发的Plugin功能。但是,cordova.exec方法需要带入的五个输入参数、加上success、error这两个Callback函式所隐含的回传参数、再加上多参数需要包装成JSON格式...这些琐碎的工作,会大量增加Web开发人员使用Plugin功能模块的负担。

    为了减少Web开发人员使用Plugin功能模块的负担,Plugin功能模块的开发人员,可以使用Cordova提供的JavaScript Module挂载机制,在Plugin功能模块里面加入JavaScript程序代码来封装cordova.exec方法,用以提供更简洁、更易懂的使用接口让Web开发人员使用。

    • Before

      cordova.exec(null, null, "NotificationService", "show", [message]);
      
    • After

      clk.cordova.sample.NotificationService.show("Clark");
      

    js-module metadata

    Cordova在编译每个执行平台的时候,会读取plugin.xml里所有的js-module设定区块,并且将每一个js-module设定区块里src所指定的js-module原始码打包备用。当应用程序执行的时候,Cordova核心会将这些js-module加载来提供Web页面使用。

    • name : js-module标识符
    • src : js-module原始码
    <!-- javascript -->
    <js-module name="NotificationService" src="www/clk.cordova.sample.NotificationService.js" >
        ...
    </js-module>
    

    js-module code

    在每个js-module原始码的内部,可以透过Cordova所提供的exports对象,来附加使用JavaScript所撰写的功能函式,这个exports对象是用来封装js-module功能的对象。在本篇的范例里,js-module原始码在exports对象上,附加了一个show函式用来简化cordova.exec的使用方式,提供给Web页面使用。

    • clk.cordova.sample.NotificationService.js

      // methods
      exports.show = function (message) {
          cordova.exec(null, null, "NotificationService", "show", [message]);
      };
      

    cordova.require

    Web页面需要使用js-module的时候,可以使用cordova.require方法来取得js-module。这个cordova.require方法,使用js-module设定区块里name所设定的名称、加上Plugin metadata里所定的id标识符做为索引,来识别并取得Cordova核心中的js-module。在本篇的范例里,Web页面使用cordova.require取得Plugin id:clk-cordova-sample、js-module name:NotificationService,封装js-module的exports对象,并且调用这个exports对象所附加的show函式。

    • index.html

      var notificationService = cordova.require("clk-cordova-sample.NotificationService");
      
      notificationService.show("Clark");
      

    clobbers

    为了更进一步简化取得js-module的方式,Cordova另外在plugin.xml的js-module设定区块上,提供了clobbers设定项目。当应用程序执行、Cordova核心加载js-module提供Web页面使用的时候,如果定义了clobbers所提供的target设定参数,Cordova核心会自动将封装js-module的exports对象,存放到target所定义的对象上,让Web页面可以直接调用。

    在本篇的范例里,js-module定义了一个clobbers的target,Cordova核心会在载入clk.cordova.sample.NotificationService.js之后,将封装js-module的exports对象,存放到clk.cordova.sample.NotificationService这个物件上。后续Web页面,只要直接使用clk.cordova.sample.NotificationService.show就可以调用这个exports对象所附加的show函式。

    • clobbers

      <!-- javascript -->
      <js-module name="NotificationService" src="www/clk.cordova.sample.NotificationService.js" >
          <clobbers target="clk.cordova.sample.NotificationService" />
      </js-module>
      
    • index.html

      clk.cordova.sample.NotificationService.show("Clark");
      

    范例下载

    范例程序代码:下载地址

  • 相关阅读:
    [转]asp.net页面缓存技术
    UL和LI在div中的高度的IE6下兼容性
    jquery制作的横向图片滚动带横向滚动条TackerScroll
    电脑可以上网,但是qq登陆不上去?
    Introduction to discrete event system学习笔记4.6
    Introduction to Discrete event system学习笔记4.9
    Introduction to discrete event systemsstudy 4.5
    Symbolic synthesis of obserability requirements for diagnosability B.Bittner,M.Bozzano,A.Cimatti,and X.Olive笔记4.16
    Introduction to discrete event system学习笔记4.8pm
    Introduction to discrete event system学习笔记 4.8
  • 原文地址:https://www.cnblogs.com/clark159/p/4906112.html
Copyright © 2011-2022 走看看