快速自定义Cordova插件(-配置文件)
一、动态改变插件参数变量
在正式开始之前先补充个知识点:
1,在安卓gradle里面有很多个控制变量,比如cdvBuildMultipleApks之类的,怎么来的呢
首先创建一个.build文件比如:config.build文件,
然后在里面定义变量如:
ext {
minSdkVersion = 14
targetSdkVersion = 23
compileSdkVersion = 23
}
也可以直接写为ext.cdvBuildMultipleApks,ext.cdvVersionCodeForceAbiDigit,ext.cdvMinSdkVersion
ext的意思是对外提供变量
我们在build.gradle(app)在中使用的cdvBuildMultipleApks可能来自于build.gradle(project)中定义,也可能来自于其他的.gradle文件,在build.gradle(app)中使用时需要引入(build.gradle(project)的除外)如:apply from "../config.gradle"
2,安卓中config.xml文件中插件的配置举例(cordova-plugin-crosswalk-webview插件):
<plugin name="cordova-plugin-crosswalk-webview" spec="^2.4.0">
<variable name="XWALK_VERSION" value="23+" />
<variable name="XWALK_LITEVERSION" value="xwalk_core_library_canary:17+" />
<variable name="XWALK_COMMANDLINE" value="--disable-pull-to-refresh-effect" />
<variable name="XWALK_MODE" value="embedded" />
<variable name="XWALK_MULTIPLEAPK" value="false" />
</plugin>
variable中name对应于插件里面的plugin.xml中$XWALK_VERSION",$XWALK_LITEVERSION,$XWALK_COMMANDLINE,$XWALK_MODE,$XWALK_MULTIPLEAPK:
在插件的plugin.xml中通过上面的方法可以获取到config.xml中插件的配置value
3,安卓中config.xml里面可以写preference开头的标签文件,如:
<preference name="StatusBarStyle" value="default" />
然后在android中的.java文件和ios中的.m文件里面可以获取到并且配置。
现在我们正式开始,以cordova-plugin-wechat这个插件举例:
plugin.xml配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
xmlns:rim="http://www.blackberry.com/ns/widgets"
xmlns:android="http://schemas.android.com/apk/res/android"
id="cordova-plugin-wechat"
version="2.1.0">
<name>Wechat</name>
<description>A cordova plugin, a JS version of Wechat SDK</description>
<license>MIT</license>
<keywords>cordova,wechat,weixin,share</keywords>
<repo>https://github.com/xu-li/cordova-plugin-wechat.git</repo>
<issue>https://github.com/xu-li/cordova-plugin-wechat/issues</issue>
<!-- add this to your config.xml -->
<!-- <preference name="WECHATAPPID" value="YOUR_WECHAT_APP_ID_HERE" /> -->
<preference name="WECHATAPPID" />
<!-- js module-->
<js-module src="www/wechat.js" name="Wechat">
<clobbers target="Wechat" />
</js-module>
<!-- ios -->
<platform name="ios">
<config-file target="config.xml" parent="/*">
<feature name="Wechat">
<param name="ios-package" value="CDVWechat"/>
<param name="onload" value="true" />
</feature>
<preference name="WECHATAPPID" value="$WECHATAPPID"/>
</config-file>
<config-file target="*-Info.plist" parent="LSApplicationQueriesSchemes">
<array>
<string>weixin</string>
<string>wechat</string>
</array>
</config-file>
<config-file target="*-Info.plist" parent="NSAppTransportSecurity">
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
</config-file>
<config-file target="*-Info.plist" parent="CFBundleURLTypes">
<array>
<dict>
<key>CFBundleURLName</key>
<string>weixin</string>
<key>CFBundleURLSchemes</key>
<array>
<string>$WECHATAPPID</string>
</array>
</dict>
</array>
</config-file>
<!-- Plugin source code -->
<header-file src="src/ios/CDVWechat.h" />
<source-file src="src/ios/CDVWechat.m" />
<!-- Wechat Official -->
<header-file src="src/ios/libs/OpenSDK1.8.0/WXApi.h" />
<header-file src="src/ios/libs/OpenSDK1.8.0/WXApiObject.h" />
<source-file src="src/ios/libs/OpenSDK1.8.0/libWeChatSDK.a" framework="true" />
<!-- Other required frameworks -->
<framework src="libz.tbd" />
<framework src="libsqlite3.0.tbd" />
<framework src="CoreTelephony.framework" />
<framework src="SystemConfiguration.framework" />
<framework src="Security.framework" />
<framework src="CFNetwork.framework" />
<framework src="libstdc++.6.tbd" />
</platform>
<!-- android -->
<platform name="android">
<hook type="after_plugin_add" src="scripts/android-install.js" />
<hook type="after_plugin_install" src="scripts/android-install.js" />
<hook type="before_plugin_rm" src="scripts/android-install.js" />
<hook type="before_plugin_uninstall" src="scripts/android-install.js" />
<config-file target="res/xml/config.xml" parent="/*">
<feature name="Wechat">
<param name="android-package" value="xu.li.cordova.wechat.Wechat"/>
</feature>
<preference name="WECHATAPPID" value="$WECHATAPPID"/>
</config-file>
<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"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</config-file>
<config-file target="AndroidManifest.xml" parent="/manifest/application">
<activity
android:name=".wxapi.WXEntryActivity"
android:label="@string/launcher_name"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="$WECHATAPPID"/>
</intent-filter>
</activity>
<activity
android:name=".wxapi.WXPayEntryActivity"
android:label="@string/launcher_name"
android:exported="true"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="$WECHATAPPID"/>
</intent-filter>
</activity>
</config-file>
<source-file src="src/android/Wechat.java" target-dir="src/xu/li/cordova/wechat" />
<source-file src="src/android/Util.java" target-dir="src/xu/li/cordova/wechat" />
<framework src="android-build.gradle" custom="true" type="gradleReference" />
</platform>
</plugin>
注:发现通过$WECHATAPPID去取到config.xml中插件配置的value的,同时发现通过在plugin.xml里面就可以把需要的信息写入到了ios中的info文件和安卓中的mainfest.xml文件中去了
安装cordova-plugin-wechat这个插件需要用户指定变量的值,需要在插件plugin.xml中添加<preference/>标签,标签有两个参数设置:name和default。
1、name:变量名称,如果需要引用name对应的value时使用$name,如 <preference name="KEY"> 引用使用 <data scheme="$KEY">;
2、default:默认值,如果用户没有指定值的时候。如果default参数未指定,则name属性用户必须填写,这也是cordova的一个策略。
使用方式:cordova plugin cordova_plugin_xxx --variable key=123456789
安卓刚刚实现了在插件里面的plugin.xml中可以去配置mainfest.xml,发现还有一个需求:就是怎么通过插件去控制gradle中的配置呢?
思路就是:在插件的src/android中创建一个.gradle文件,然后在里面写配置,同时可以根据插件里面的plugin.xml中的变量做不同的处理,还以开头讲的第二个知识点为例,
插件中的plugin.xml中其中有一个配置文件如下:
<config-file target="res/xml/config.xml" parent="/*">
<preference name="webView" value="org.crosswalk.engine.XWalkWebViewEngine"/>
<preference name="xwalkVersion" value="$XWALK_VERSION"/>
<preference name="xwalkLiteVersion" value="$XWALK_LITEVERSION"/>
<preference name="xwalkCommandLine" value="$XWALK_COMMANDLINE"/>
<preference name="xwalkMode" value="$XWALK_MODE" />
<preference name="xwalkMultipleApk" value="$XWALK_MULTIPLEAPK" />
<preference name="android-minSdkVersion" value="16" />
</config-file>
在xwalk.gradle文件中 ext.xwalkMode = getConfigPreference("xwalkMode");,
这里getConfigPreference("xwalkMode");里面的“xwalkMode”红字部分是对应的。
二、自定义插件中需要引入第三方库
1, 安卓中自定义插件需要引入jar包,这个问题搞了一天才搞好,被网上的贴子和老的demo给坑了,有个demo是拿jpush举例子的
如下:
<!--需要引入jar包时添加此处代码-->
<source-file src="src/android/jpush-sdk-release1.7.5.jar" target-dir="libs"/>
实践证明上面是错误的,看cordova官方有两种做法:
The preferred way is to use the <framework /> tag (see the Plugin Specification for more details). Specifying libraries in this manner allows them to be resolved via Gradle's Dependency Management logic. This allows commonly used libraries such as gson, android-support-v4, and google-play-services to be used by multiple plugins without conflict.
The second option is to use the <lib-file /> tag to specify the location of a jar file (see the Plugin Specification for more details). This approach should only be used if you are sure that no other plugin will be depending on the library you are referencing (e.g. if the library is specific to your plugin). Otherwise, you risk causing build errors for users of your plugin if another plugin adds the same library. It is worth noting that Cordova app developers are not necessarily native developers, so native platform build errors can be especially frustrating.
意思是说一种通过<framework>另一种是通过<lib-file>,第一种方式试了很多遍就是不成功,无奈试了第二种方式成功了。
过程如下:src/android/libs中放入需要引用的jar包
如上我是自定义友盟统计的插件,然后在plugin.xml中写入:
<lib-file src="src/android/libs/umeng-analytics-7.4.0.jar" />
<lib-file src="src/android/libs/umeng-common-1.4.0.jar" />
<lib-file src="src/android/libs/utdid4all-1.1.5.3_proguard.jar" />
2,ios中添加framework(依然拿友盟framework举例)
<framework src="src/ios/UMAnalytics.framework" custom="true" />
<framework src="src/ios/UMCommon.framework" custom="true" />
注意的地方是framework有可能会依赖系统的库,比如友盟这里就需要添加:
<framework src="libz.tbd" weak="true" />
<framework src="libsqlite3.0.tbd" weak="true" />
Frame with sticks of ceylon cinnamon on wooden