从零创建cordova插件(包括四大组件、架包、生命周期)

2020/6/15 23:26:41

本文主要是介绍从零创建cordova插件(包括四大组件、架包、生命周期),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

1 介绍

本文将细致讲解cordova插件的创建、编写、plugin.xml配置、aar+jar+so架包配置、静态资源配置、四大组件

2 开始整活一个简单cordova插件

2.1 初始化Cordova插件开发目录

初始化之前确保安装Cordova

cordova create CordovaProject io.cordova.hellocordova CordovaApp
复制代码
CordovaProject               是创建应用程序的目录名称。
io.cordova.hellocordova      是默认的反向域值。 如果可能,您应该使用您自己的域值。
CordovaApp                   是您应用的标题。
复制代码

本人在jobProject下创建 CordovaProject

$ cordova create CordovaProject com.ths.toast ThsToast
复制代码

此时根目录下会生成如下结构

在添加platforms和plugins之后,可以在此目录下打包

CordovaProject$ cordova build android
复制代码

应用的包名就是com.ths.toast,应用名称就是ThsToast

2.2 安装plugman

plugman是用于安装和卸载用于Apache Cordova项目的插件的命令行工具。 进入CordovaProject项目目录,安装plugman

$ npm install -g plugman
复制代码

2.3 创建插件

2.3.1创建一个最简单的Toast插件

$ plugman create --name [插件名] --plugin_id [插件id] --plugin_version [插件版本]
复制代码

为了方便管理,将插件创建在 Cordova 项目目录下的 plugins 文件夹下

plugins$ plugman create --name ThsToast --plugin_id cordova-plugin-ths-toast --plugin_version 1.0.0
复制代码

接着手动将ThsToast目录重命名为和上述plugin_id一样的值:cordova-plugin-ths-toast,这里以及上面的ths表示的是公司的统一标识,通常是英文字符串

进入插件目录,添加插件支持的平台环境

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,实践出真知,这篇文章还是写了一周,毕竟是个前端开发,若有总结不到位或者遗漏的地方,还请各位大佬多多指出,谢谢大家!如果这篇文章对前端或其他方向的你有所帮助或者启发,记得点个赞哦亲:)



这篇关于从零创建cordova插件(包括四大组件、架包、生命周期)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程