從零建立cordova插件(包括四大組件、架包、生命週期)

1 介紹

本文將細緻講解cordova插件的建立、編寫、plugin.xml配置、aar+jar+so架包配置、靜態資源配置、四大組件php

2 開始整活一個簡單cordova插件

2.1 初始化Cordova插件開發目錄

初始化以前確保安裝Cordovahtml

cordova create CordovaProject io.cordova.hellocordova CordovaApp
CordovaProject               是建立應用程序的目錄名稱。
io.cordova.hellocordova      是默認的反向域值。 若是可能,您應該使用您本身的域值。
CordovaApp                   是您應用的標題。

本人在jobProject下建立 CordovaProject前端

$ cordova create CordovaProject com.ths.toast ThsToast

此時根目錄下會生成以下結構vue


在添加platforms和plugins以後,能夠在此目錄下打包java

CordovaProject$ cordova build android

應用的包名就是com.ths.toast,應用名稱就是ThsToastnode

2.2 安裝plugman

plugman是用於安裝和卸載用於Apache Cordova項目的插件的命令行工具。
進入CordovaProject項目目錄,安裝plugmanlinux

$ npm install -g plugman

2.3 建立插件

2.3.1建立一個最簡單的Toast插件

$ plugman create --name [插件名] --plugin_id [插件id] --plugin_version [插件版本]

爲了方便管理,將插件建立在 Cordova 項目目錄下的 plugins 文件夾下android

plugins$ plugman create --name ThsToast --plugin_id cordova-plugin-ths-toast --plugin_version 1.0.0


接着手動將ThsToast目錄重命名爲和上述plugin_id同樣的值:cordova-plugin-ths-toast,這裏以及上面的ths表示的是公司的統一標識,一般是英文字符串ios

進入插件目錄,添加插件支持的平臺環境git

cordova-plugin-ths-toast$ plugman platform add --platform_name android
cordova-plugin-ths-toast$ plugman platform add --platform_name ios

添加以後將在cordova-plugin-ths-toast目錄下產生android和ios兩個目錄,此處只定義android環境的ThsToast,
生成的文件內容如圖所示


注意:起名不要和安卓原生方法衝突了,好比這裏ThsToast若是改爲Toast,就會和android.widget.Toast中的Toast類重名,致使構建報錯


2.3.2 插件配置

添加完平臺後,cordova-plugin-ths-toast 目錄下的 plugin.xml 文件將添加以下內容

修改 plugin.xml 文件內容以下

<?xml version='1.0' encoding='utf-8'?>
<plugin id="cordova-plugin-ths-toast" version="1.0.0" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
    <name>Toast</name>
    <js-module name="ThsToast" src="www/ThsToast.js">
        <!-- target修改, 經過window.ThsToast.show或ThsToast.show便可調用api -->
        <clobbers target="ThsToast" />
    </js-module>

    <platform name="android">
        <config-file parent="/*" target="res/xml/config.xml">
            <feature name="ThsToast">
            <!-- param value修改,指向最終打包輸出的主類完整路徑 -->
                <param name="android-package" value="org.apache.cordova.thstoast.ThsToast" />
            </feature>
        </config-file>
        <config-file parent="/*" target="AndroidManifest.xml" />
        <!-- target-dir修改,輸出到最終打包輸出的主類完整目錄路徑 -->
        <source-file src="src/android/ThsToast.java" target-dir="src/org/apache/cordova/thstoast" />
    </platform>

    <platform name="ios">
        <config-file parent="/*" target="config.xml">
            <feature name="ThsToast">
                <param name="ios-package" value="ThsToast" />
            </feature>
        </config-file>
        <source-file src="src/ios/ThsToast.m" />
    </platform>
</plugin>

修改www/ThsToast.js,順帶提一下其中exec方法就是調用cordova插件的原始方法,該方法傳的'ThsToast','show'和[arg0],success,error參數對應的分別是android/ThsToast.java中的class類名,action和args,callbackContext.success,callbackContext.error



修改 android/ThsToast.java 文件,

2.3.3 寫好README,給人魚不放心,再給人漁杆

cordova-plugin-ths-toast$ touch README.md

2.3.4 初始化插件

npm init

提示的時候name輸入插件id,其他根據提示填寫,不清楚就直接按回車到結束,將建立一個 package.json 文件

{
  "name": "cordova-plugin-ths-toast",
  "version": "1.0.0",
  "description": "show toast",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/qtpalmtop/cordova-plugin-ths-toast.git"
  },
  "author": "lilin",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/qtpalmtop/cordova-plugin-ths-toast/issues"
  },
  "homepage": "https://github.com/qtpalmtop/cordova-plugin-ths-toast#readme"
}

接着修改package.json,keywords關鍵字配置是爲了在Cordova Plugin Search中顯示插件,engines配置是插件可能會列出多個發行版的依賴關係,以便在Cordova CLI選擇要從npm獲取的插件版本時向其提供指導,旨在最終替換plugin.xml中的engine元素。
詳細內容請參考cordova建立插件

{
  "name": "cordova-plugin-ths-toast",
  "version": "1.0.0",
  "description": "show toast",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/qtpalmtop/cordova-plugin-ths-toast.git"
  },
  "author": "lilin",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/qtpalmtop/cordova-plugin-ths-toast/issues"
  },
  "homepage": "https://github.com/qtpalmtop/cordova-plugin-ths-toast#readme",
  "keywords": [
    "ecosystem:cordova",
    "cordova-android",
    "cordova-ios"
  ],
  "engines": {
    "cordovaDependencies": {
      "2.0.0": {
        "cordova-android": ">=3.6.0"
      },
      "4.0.0": {
        "cordova-android": ">=3.6.0",
        "cordova-windows": ">=4.4.0"
      },
      "6.0.0": {
        "cordova": ">100"
      }
    },
    "node": ">=6.0.0"
  }
}

2.3.5 發佈插件

發佈後就能夠正常的經過cordova plugin add cordova-plugin-ths-toast在項目中經過ThsToast.show()使用,可是要在angular項目中使用還須要咱們開發自定義插件api,下面咱們開始ionic-native的api模塊開發

cd cordova-plugin-ths-toast
npm login
npm publish

3 cordova開發進階

3.1 Activity:四大組件之活動

簡單來講,活動至關於angular的page,vue的vue,是一個可包含組件(fragment)的ui頁面。

1.開啓普通活動

// 應用上下文
Context context = cordova.getActivity().getApplicationContext();
String pkgName  = context.getPackageName();

// 打開app應用
Intent intent = context
        .getPackageManager()
        .getLaunchIntentForPackage(pkgName);

// 打開XxxActivity
// Intent intent=new Intent(cordova.getActivity(), XxxActivity.class);

// 打開應用必需要加 CATEGORY_LAUNCHER
intent.addCategory(Intent.CATEGORY_LAUNCHER);

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);

// 啓動應用
context.startActivity(intent);

// 啓動活動
// cordova.getActivity().startActivity(intent);

// 啓動有返回值的活動
// cordova.startActivityForResult((CordovaPlugin) this, intent, 0);
  1. 打開第三方Android SDK活動 如:百度地圖uri
// 若是有百度地圖 uri詳情:http://lbsyun.baidu.com/index.php?title=uri/api/android
Intent intent = Intent.parseUri("intent://map/direction?"
                        + "origin="+options.getOrigin4Baidu()
                        + "&destination="+options.getDestination4Baidu()
                        + "&mode="+options.getModel4Baidu()
                        + "&coord_type=wgs84&referer=Autohome|GasStation#Intent;scheme=bdapp;package=com.baidu.BaiduMap;end",0);
                        
cordova.getActivity().startActivity(intent);

3.2 BroadcastReceiver: 四大組件之廣播

廣播其實就是一個在app範圍內的事件推送和接受中心,相似於iframe的postMessage。

和原生廣播沒有區別,通常靜態廣播用在插件比較多

plugin.xml 靜態註冊廣播

3.3 Service: 四大組件之服務

服務能夠同步或執行一些小任務、小進程,甚至對其餘進程的ui頁面作操做,可類比angular的service服務。

和原生Service同樣的用法

plugin.xml

3.4 ContentProvider: 四大組件以內容提供者

內容提供者實際上是一個手機系統範圍的API調度中心,好比能夠讀取和修改通信錄和相冊的內容。


plugin.xml, 訪問其餘應用的內容須要配置應用讀寫權限

<config-file target="AndroidManifest.xml" parent="/manifest">
  <uses-permission android:name="android.permission.READ_CALENDAR"/>
  <uses-permission android:name="android.permission.WRITE_CALENDAR"/>
</config-file>

<!-- 若是不是上面Calendar這種系統provider(android.provider.*),則須要註冊 -->
<config-file target="AndroidManifest.xml" parent="/*/application">
    <provider
        android:name="org.apache.cordova.provider.TestContentProvider"
        android:authorities="org.apache.cordova.provider.testprovider"
        android:exported="false" />
</config-file>

3.5 jar、aar、so架包和資源配置

3.5.1 jar

jar包能夠理解爲api的集合,解壓後所有是編譯好的class,可是不包含資源文件,能夠直接使用使用其中的類。

引入jar包類

jar包路徑位於libs目錄下


plugin.xml

3.5.2 so

so是在NDK平臺開發的,NDK是用來給安卓手機開發軟件用的,可是和SDK不一樣的是它用的是C語言,而SDK用的是Java語言。NDK開發的軟件在安卓的環境裏是直接運行的,通常只能在特定的CPU指令集的機器上運行。

so配置在libs目錄下便可

3.5.3 aar

aar和jar相似,可是他包含了全部資源,class以及res資源文件

aar和gradle放在libs下

gradle中要在repositories中配置flatDir,dependencies中配置compile

plugin.xml

使用:例如跳轉activity

3.5.4 靜態資源和java文件配置

靜態資源放在res目錄下


plugin.xml 經過resource-file和source-file配置當前路徑和輸出路徑,靜態資源默認路徑是src/android/res/xxx, 輸出路徑是res/xxx,java文件默認路徑是src/android/Xxx.java 輸出目錄是src/包/名/字/,注意target-dir是目錄路徑,target纔是文件路徑。

3.6 meta-data: 添加插件時傳入參數

拿一個分享插件舉例作示範

plugin.xml:配置preference,用於接收用戶傳參variable的值,config-file中配置meta-data, 保存參數鍵值信息用於給java類調用。


Plugin.java:經過cordova.getActivity().getPackageManager().getApplicationInfo(cordova.getActivity().getPackageName(), PackageManager.GET_META_DATA)獲取參數存儲的對象appInfo,再經過appInfo.metaData.getType(key)取得參數value,getType有getString、getInt……

傳入插件參數有兩種辦法,

1.用cordova 安裝時利用--variable key=value 傳入

cordova plugin add cordova-plugin-share --variable WEIXIN_APP_ID=xxx --variable WEIXIN_APP_SECRET=xxx --variable QQ_APP_ID=xxx --variable QQ_APP_KEY=xxx

2.添加插件完成後,在項目的config.xml中手動添加

<plugin name="cordova-plugin-share" spec="1.0.0">
    <variable name="WEIXIN_APP_ID" value="xxx" />
    <variable name="WEIXIN_APP_SECRET" value="xxx" />
    <variable name="QQ_APP_ID" value="xxx" />
    <variable name="QQ_APP_KEY" value="xxx" />
</plugin>

3.7 權限

當須要使用系統的某個功能時,必定要加上權限詢問配置,全部的權限在這查看

<config-file target="AndroidManifest.xml" parent="/manifest">
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
</config-file>

3.8 CordovaPlugin生命週期和自帶方法

3.9.1 excute:執行插件方法

調用插件執行方法。第一個參數action是調用的方法名,第二個參數args是傳入的參數數組,第三個參數CallbackContext是傳入的回調函數上下文,能夠經過callbackContext.success(message)和callbackContext.error(errorMessage)傳入回調參數;

@Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
}

3.8.2 initialize:初始化

在插件構造函數執行和字段初始化以後調用,此時還沒有執行excute方法。

@Override
public void initialize (CordovaInterface cordova, CordovaWebView webView) {}

3.8.3 pluginInitialize:無參初始化

在插件構造函數執行和字段初始化以後調用,沒有參數,此時還沒有執行excute方法,pluginInitialize 不支持 cordova 3.0-3.5 。

@Override
protected void pluginInitialize() {}

3.8.4 onStart:活動開始週期

活動正在被啓動,已經可見,可是還沒位於前臺。

@Override
public void onStart() {}

3.8.5 onResume:活動恢復週期

活動位於前臺,而且能夠與用戶交互了。

/**
 * 當活動將開始與用戶互動時調用。
 *
 * @param multitasking 表示是否爲應用程序打開了多任務
 */
@Override
public void onResume(boolean multitasking) {
    super.onResume(multitasking);
    // deviceready();
}

3.8.6 onPause:活動暫停週期

活動處於正在中止的狀態,一般當要離開這活動的時候會被調用。接下去onStop()立刻會被調用,若是是彈出一個對話框,那麼onStop不會被調用。

/**
 * 在系統即將開始恢復上一個活動時調用
 *
 * @param multitasking 表示是否爲應用程序打開了多任務
 */
@Override
public void onPause(boolean multitasking) {
    super.onPause(multitasking);
}

3.8.7 onStop:活動中止週期

活動即將中止,活動徹底不可見。

/**
 * 活動中止前調用
 */
@Override
public void onStop() {
    super.onStop();
}

3.8.8 onReset:活動重置週期

這個方法表示活動正在從新啓動,活動由中止狀態恢復爲運行狀態,一般由上一個活動返回到這個活動時,這個活動會調用此方法。

/**
 * 當視圖導航時調用
 */
@Override
public void onReset() {}

3.8.9 onActivityResult:返回活動數據

當從另外一個活動返回到當前活動時,當前活動中的onActivityResult可接收剛纔活動的返回數據。

@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);
}

3.8.10 onDestroy:活動銷燬週期

活動徹底銷燬前調用,能夠在這作一些資源釋放的操做。

/**
 * 活動銷燬前調用
 */
@Override
public void onDestroy() {
    // deviceready = false;
}

4 總結

咱們從建立一個簡單的cordova自定義插件,到四大組件的配置和使用,還講了如何導入jar、aar、so、靜態資源,最後概括了經常使用的生命週期,看到這,咱們應該已經具有獨立建立和改寫插件的基本能力,剩下的就只有本身多看多用cordova-plugin,實踐出真知,這篇文章仍是寫了一週,畢竟是個前端開發,如有總結不到位或者遺漏的地方,還請各位大佬多多指出,謝謝你們!若是這篇文章對前端或其餘方向的你有所幫助或者啓發,記得點個贊哦親:)

相關文章
相關標籤/搜索