cordova3.X 運(yùn)用grunt快速生成plugin自定義插件骨架

Cordova提供了一組設(shè)備相關(guān)的API蒲障,通過(guò)這組API锡宋,移動(dòng)應(yīng)用能夠以JavaScript訪問(wèn)原生的設(shè)備功能,如攝像頭媳否、麥克風(fēng)等栅螟。Cordova還提供了一組統(tǒng)一的JavaScript類庫(kù),以及為這些類庫(kù)所用的設(shè)備相關(guān)的原生后臺(tái)代碼篱竭。

一力图、安裝cordova
npm install -g cordova
二、創(chuàng)建項(xiàng)目
cordova create hello com.blue.sky.hybrid.app.hello HelloWorld
三掺逼、添加平臺(tái)支持
cd hello
cordova platform add android`(前提是系統(tǒng)上面要安裝了對(duì)應(yīng)移動(dòng)系統(tǒng)的SDK)
四吃媒、自定義插件

學(xué)了這么多, 準(zhǔn)備自己寫個(gè)自定義插件,變?cè)诿钚休斎耄篶ordova plugin create com.blue.sky.test 發(fā)現(xiàn)不管用. 查閱資料后, 發(fā)現(xiàn)沒(méi)有這個(gè)命令, 網(wǎng)上大家都是手動(dòng)創(chuàng)建目錄, 覺(jué)得太麻煩, 于是用grunt 寫了一個(gè)命令通過(guò)模板生成cordova plugin骨架吕喘。

》》網(wǎng)上的方法大概是這樣:

cordova3.X之后,插件不能自己手動(dòng)添加了,手動(dòng)添加后,只要cordova build,數(shù)據(jù)立即被抹去.
因此,3.X后要添加插件,需要用 cordova plungin add "你本地插件的路徑" 的方式來(lái)添加插件,.
1.新建一個(gè)文件夾,命名為你插件的名字,如TestPlugin
2.在文件夾里再新建2個(gè)文件夾和1個(gè)文件.兩個(gè)文件夾分別是src和www.其中src中放你插件的java代碼,www中放對(duì)應(yīng)的js文件;與src和www文件夾同級(jí),建立plugin.xml

》》運(yùn)用grunt模板生成cordova plugin骨架

思路:cordova plugin 主要是三個(gè)文件:
1赘那、繼承cordovaActivity的Native實(shí)現(xiàn)類
2、編寫javascript代碼
3氯质、編寫plugin.xml配置文件

既然是這樣, 便可以運(yùn)用grunt通過(guò)模板生成cordova plugin骨架募舟。
首先看一下項(xiàng)目代碼結(jié)構(gòu):


第一步:制定cordova plugin模板

模板內(nèi)容如下:
**src/android/template.txt **繼承cordovaActivity的Native實(shí)現(xiàn)類

package <%=pkgName%>;
 
import java.util.TimeZone;
 
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CordovaInterface;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
 
import android.provider.Settings;
 
public class <%=className%> extends CordovaPlugin {
 
    public <%=className%>() {
 
    }
 
    /**
     * Executes the request and returns PluginResult.
     *
     * @param action            The action to execute.
     * @param args              JSONArry of arguments for the plugin.
     * @param callbackContext   The callback id used when calling back into JavaScript.
     * @return                  True if the action was valid, false if not.
     */
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
 
        ///TODO 自定義實(shí)現(xiàn)
 
        return true;
    }
 
}

**www/template.txt **javascript 模板

var channel = require('cordova/channel'),
  utils = require('cordova/utils'),
  exec = require('cordova/exec'),
  cordova = require('cordova');
 
function <%=className%>() {
 
}
 
module.exports = new <%=className%>();

plugin.xml 插件編譯生成android 項(xiàng)目代碼配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!--插件id號(hào),與package.json保持一致 版本號(hào)闻察,與package.json保持一致-->
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
        id="<%=pkgName%>" version="0.1">
    <!--插件在cordova下的名稱拱礁,Test.js中exec的接口名稱,保持一致-->
    <name><%=className%></name>
    <description>Cordova Plugin</description>
    <license>Apache 2.0</license>
    <!--與package.json保持一致-->
    <keywords></keywords>
    <repo></repo>
    <issue></issue>
    <!--插件js接口文件配置信息蜓陌,插件在android-->
    <!--src="www/Test.js"為已經(jīng)寫好的js文件路徑觅彰,與js中調(diào)用的類名保持一致-->
    <js-module src="www/<%=className%>.js" name="<%=className%>">
        <!--插件在js中調(diào)用的類名-->
        <clobbers target="<%=className%>" />
    </js-module>
 
    <!-- android -->
    <platform name="android">
        <config-file target="res/xml/config.xml" parent="/*">
            <!--插件在java端的接口名稱,與之前文件中的接口名稱保持一致-->
            <feature name="<%=className%>">
                <!--該插件接口對(duì)應(yīng)的java代碼路徑-->
                <param name="android-package" value="<%=pkgName%><%=className%>"/>
            </feature>
        </config-file>
 
        <!--該插件需要的權(quán)限申明钮热,根據(jù)需要自行定義-->
        <config-file target="AndroidManifest.xml" parent="/*">
            <uses-permission android:name="android.permission.INTERNET" />
            <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
            <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
        </config-file>
 
        <!--源文件的路徑和目標(biāo)文件路徑填抬,src為已經(jīng)編寫好的java代碼路徑,target-dir為需要生成的android工程中該java源碼路徑隧期,與上面的java代碼路徑保持一致-->
        <source-file src="<%=sourceSrc%>" target-dir="<%=targetDir%>"/>
 
    </platform>
 
</plugin>

運(yùn)用Node.js grunt根據(jù)模板生成骨架代碼:
grunt plugin:create:com.blue.sky.test:Test

module.exports = function(grunt) {
    grunt.registerTask('plugin:create', '自定義插件 參數(shù)一 包名  參數(shù)二 插件類名', function (arg1, arg2, arg3) {
        grunt.log.writeln(">>>>length:" + arguments.length);
        if (arguments.length === 2) {
     
          var pkgName = arg1;
          var fileName = arg2;
          var platform = arg3 || "android";
          var pluginDir = "temp/" + arg1;
          var tplNativeCode = "template/src/" + platform + "/template.js";
          var tplJSCode = "template/www/template.js";
          var tplPlugin = "template/plugin.xml";
     
          var srcFileName = pluginDir + "/src/" + platform + "/" + arg2 + ".java";
          var jsFileName = pluginDir + "/www/" + arg2 + ".js";
          var configFileName = pluginDir + "/plugin.xml";
     
          grunt.log.writeln("start create plugin:" + arg1);
     
          grunt.file.mkdir(pluginDir);
     
          // 創(chuàng)建插件java類
          grunt.file.mkdir(pluginDir + "/src/" + platform);
          grunt.file.write(srcFileName, grunt.file.read(tplNativeCode));
          var content = grunt.file.read(srcFileName);
          var text = grunt.template.process(content, {data: {"pkgName": pkgName + "." + fileName, "className": fileName}});
          grunt.file.write(srcFileName, text);
     
          // 創(chuàng)建插件javascript
          grunt.file.mkdir(pluginDir + "/www");
          grunt.file.write(jsFileName, grunt.file.read(tplJSCode));
          var jsContent = grunt.file.read(jsFileName);
          var jsText = grunt.template.process(jsContent, {data: {"className": fileName}});
          grunt.file.write(jsFileName, jsText);
     
          // 創(chuàng)建插件配置文件plugin.xml
          var configContent = grunt.file.read(tplPlugin);
          var configText = grunt.template.process(configContent,
            {
              data: {
                "pkgName": pkgName,
                "className": fileName,
                "sourceSrc":"src/"+ platform + "/" + fileName +  ".java",
                "targetDir":"src/" + pkgName.replace(/\./g,"/")
              }
            }
          );
          grunt.file.write(configFileName, configText);
     
     
          grunt.log.writeln("create plugin success");
     
        } else {
          grunt.log.writeln("命令格式錯(cuò)誤飒责。 grunt plugin:create 包名 插件類名");
        }
    });
}

使用cordova plugin add "本地自定義插件代碼"

cordova plugin add "D:\Project\workspace\phonegap\hello\temp\com.blue.sky.test"

運(yùn)行之后, 在plugins 目錄下面會(huì)看到有com.blue.sky.test插件(請(qǐng)看項(xiàng)目結(jié)果圖)赘娄。

運(yùn)行cordova run android 命令打包程序到手機(jī)
運(yùn)行后,查看platforms目錄下面生成了自定義的相關(guān)代碼宏蛉,如下圖所示:

總結(jié)

通過(guò)運(yùn)用grunt生成cordova plugin 可以很方面的創(chuàng)建plugin骨架, 省去繁瑣的步驟遣臼。當(dāng)然, 這個(gè)demo只是實(shí)現(xiàn)了android平臺(tái)的plugin。如果要支持ios拾并、wp也比較簡(jiǎn)單揍堰,只需要加相應(yīng)的模板以及映射關(guān)系即可。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末嗅义,一起剝皮案震驚了整個(gè)濱河市屏歹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌之碗,老刑警劉巖蝙眶,帶你破解...
    沈念sama閱讀 217,907評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異褪那,居然都是意外死亡幽纷,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門博敬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)友浸,“玉大人,你說(shuō)我怎么就攤上這事冶忱∥补剑” “怎么了?”我有些...
    開封第一講書人閱讀 164,298評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵囚枪,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我劳淆,道長(zhǎng)链沼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,586評(píng)論 1 293
  • 正文 為了忘掉前任沛鸵,我火速辦了婚禮括勺,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘曲掰。我一直安慰自己疾捍,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評(píng)論 6 392
  • 文/花漫 我一把揭開白布栏妖。 她就那樣靜靜地躺著乱豆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪吊趾。 梳的紋絲不亂的頭發(fā)上宛裕,一...
    開封第一講書人閱讀 51,488評(píng)論 1 302
  • 那天瑟啃,我揣著相機(jī)與錄音,去河邊找鬼揩尸。 笑死蛹屿,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的岩榆。 我是一名探鬼主播错负,決...
    沈念sama閱讀 40,275評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼勇边!你這毒婦竟也來(lái)了犹撒?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,176評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤粥诫,失蹤者是張志新(化名)和其女友劉穎油航,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體怀浆,經(jīng)...
    沈念sama閱讀 45,619評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡谊囚,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了执赡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片镰踏。...
    茶點(diǎn)故事閱讀 39,932評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖沙合,靈堂內(nèi)的尸體忽然破棺而出奠伪,到底是詐尸還是另有隱情,我是刑警寧澤首懈,帶...
    沈念sama閱讀 35,655評(píng)論 5 346
  • 正文 年R本政府宣布绊率,位于F島的核電站,受9級(jí)特大地震影響究履,放射性物質(zhì)發(fā)生泄漏滤否。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評(píng)論 3 329
  • 文/蒙蒙 一最仑、第九天 我趴在偏房一處隱蔽的房頂上張望藐俺。 院中可真熱鬧,春花似錦泥彤、人聲如沸欲芹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)菱父。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間滞伟,已是汗流浹背揭鳞。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留梆奈,地道東北人野崇。 一個(gè)月前我還...
    沈念sama閱讀 48,095評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像亩钟,于是被迫代替她去往敵國(guó)和親乓梨。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理清酥,服務(wù)發(fā)現(xiàn)扶镀,斷路器,智...
    卡卡羅2017閱讀 134,656評(píng)論 18 139
  • 主要的目的就在這了,我要學(xué)習(xí)一下怎么寫cordova插件辱志,如何調(diào)試蝠筑,如何寫config plugin.xml文件...
    wyude閱讀 323評(píng)論 0 0
  • 創(chuàng)建Cordova項(xiàng)目 一、環(huán)境配置(mac版): 1.安裝node.js(https://nodejs.org/...
    XDUZ閱讀 1,359評(píng)論 1 3
  • 所有項(xiàng)目的構(gòu)建都是有生命周期的揩懒,這個(gè)生命周期包括:項(xiàng)目清理什乙、初始化、編譯已球、測(cè)試臣镣、打包、集成測(cè)試智亮、驗(yàn)證忆某、部署、站點(diǎn)生...
    zlcook閱讀 2,769評(píng)論 0 21
  • Cordova自定義插件實(shí)戰(zhàn)# 使用前提 這篇文章是之前發(fā)表在CSDN上的阔蛉,拿過(guò)來(lái)充數(shù)用的褒繁,其實(shí)那個(gè)時(shí)候也寫了不少...
    one_cup閱讀 1,566評(píng)論 5 3