使用cordova开发应用,已经有三个月了,期间也是走了不少的弯路,经常在各种诡异的地方卡住。现在,对于安卓工程的结构也算是有了个大概的认识(被迫
插件编写
插件是cordova很重要的组成部分,将原生部分全部放到插件中,可以使整个工程更加灵活,也可以提高代码的复用性。
自己写的插件,在安装时,可以使用--link
命令,就不会是拷贝,而是链接,这样当插件代码修改时,就不需要重新add了。
cordova插件的核心之一是plugin.xml文件,通过这个xml可以应付绝大多数的情况,文件拷贝、JS对象引入、AndroidManifest.xml属性添加都可以通过这个文件来处理。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39<?xml version='1.0' encoding='utf-8'?>
<plugin id="cordova-plugin-test" version="1.0.0"
xmlns="http://apache.org/cordova/ns/plugins/1.0"
xmlns:android="http://schemas.android.com/apk/res/android">
...
<!-- 声明插件JS对象 -->
<js-module name="CordovaPluginTest" src="www/CordovaPluginTest.js">
<clobbers target="CordovaPluginTest" />
</js-module>
...
<platform name="android">
<!-- 修改res/xml/config.xml文件,声明插件java文件的位置 -->
<config-file parent="/*" target="res/xml/config.xml">
<feature name="CordovaPluginTest">
<param name="android-package" value="cordova.plugin.Test.CordovaPluginTest" />
<param name="onload" value="true"/>
</feature>
</config-file>
<!-- 修改AndroidManifest.xml文件,添加权限等需要的参数 -->
<config-file target="AndroidManifest.xml" parent="/manifest">
<uses-permission android:name="android.permission.INTERNET" />
...
</config-file>
<!-- 修改AndroidManifest.xml文件中的application属性,添加activity等需要的参数 -->
<config-file target="AndroidManifest.xml" parent="/manifest/application">
<activity
...
...
/>
</config-file>
...
<!-- 拷贝src/android/res/xml下的test.xml到res/xml下 -->
<source-file src="src/android/res/xml/test.xml" target-dir="res/xml"/>
...
<!-- 声明自定义的build.gradle文件 -->
<framework src="src/android/build.gradle" custom="true" type="gradleReference"/>
</platform>
...
</plugin>
但是,有一些时候,单靠这个配置是无法满足需求的,主要是由于包名各不相同引起的。这个时候,就需要使用脚本来完成了。
在plugin.xml中的<platform name="android">
中添加<hook>
标签1
2
3
4
5
6
7
8
9
10
11
12
13
14<?xml version='1.0' encoding='utf-8'?>
<plugin id="cordova-plugin-test" version="1.0.0"
xmlns="http://apache.org/cordova/ns/plugins/1.0"
xmlns:android="http://schemas.android.com/apk/res/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" />
...
</platform>
...
</plugin>
其中声明的android-install.js会在插件(每一个)安装时执行,利用这个脚本,就可以做到动态的调整代码,动态的拷贝文件了。
1 |
|
其中path和fs可以直接引用,但是shelljs必须要用npm安装到插件的根目录里才可以调用到,用npm i -g是不管用的。
通过path和fs以及shell,就可以做到批量修改文件中的包名并拷贝1
2
3
4
5
6
7
8
9
10
11
12
13
14
15var fromDir = path.join(projectRoot, "res", "android");
var targetDir = path.join(projectRoot, "platforms", "android", "app", "src", "main", "res", "drawable");
var targetFiles = [
"sky.png",
"logo.png"
]
if (['after_plugin_add', 'after_plugin_install'].indexOf(context.hook) >= 0) {
targetFiles.forEach(function (f) {
fs.copyFile(path.join(fromDir, f), path.join(targetDir, f), (err) => {
if (err) throw err;
console.log('copy error');
});
console.log("img copy done: " + path.join(fromDir, f))
});
}