最近在给Cordova
包装APP
集成极光推送的厂商通道,发现厂商通道都需要在模块级build.gradle
添加依赖项,不过这个文件在platforms/android/app
目录下,在Cordova
官方说明中是不推荐修改的,因为这个文件是自动生成的,如果修改了再次cordova platform add android
的话就会被覆盖,因此需要使用到build-extras.gradle
以及使用hook
复制文件。
备注:目前对于项目级的build.gradle没有build-extras.gradle支持,只能采用文件内容替换来修改
新增build-extras.gradle
参考文档:https://cordova.apache.org/docs/en/latest/guide/platforms/android/index.html#extending-buildgradle
文档里面提到了扩展build.gradle
使用build-extras.gradle
文件,而不建议手动修改的
If you need to customize
build.gradle
, rather than edit it directly, you should create a sibling file namedbuild-extras.gradle
. This file will be included by the mainbuild.gradle
when present. This file must be placed in theapp
folder of the Android platform directory (<your-project>/platforms/android/app
), so it is recommended that you copy it over via a script attached to thebefore_build
hook.
文档提到新建一个名叫build-extras.gradle
的文件,并放到<your-project>/platforms/android/app
文件夹中,这样就会自动使用上build-extras.gradle
中定义的配置项了,因此我们可以在外面新建好该文件,然后复制到指定目录就可以了。
参考目录结构,新建一个android_custom
目录,把需要复制到android
平台下面的数据放到该文件夹下面,截图里的arr
是OPPO
推送需要的依赖文件。

build-extras.gradle文件内容
build-extras.gradle文件内容自己实际情况定义就可以:
android {
defaultConfig {
manifestPlaceholders=[
JPUSH_PKGNAME : privateHelpers.extractStringFromManifest("package"),
VIVO_APPKEY : "xxxx", // VIVO平台注册的appkey
VIVO_APPID : "xxxx", // VIVO平台注册的appid
XIAOMI_APPKEY : "MI-xxxx",// 小米平台注册的appkey
XIAOMI_APPID : "MI-xxxx", // 小米平台注册的appid
OPPO_APPKEY : "OP-xxxx",
OPPO_APPID : "OP-xxxx",
OPPO_APPSECRET: "OP-xxxx",
MEIZU_APPKEY : "MZ-xxxx", // 魅族平台注册的appkey
MEIZU_APPID : "MZ-xxxx", // 魅族平台注册的appid
]
}
}
dependencies {
implementation 'cn.jiguang.sdk.plugin:vivo:4.2.8'
implementation 'cn.jiguang.sdk.plugin:xiaomi:4.2.8'
implementation 'cn.jiguang.sdk.plugin:oppo:4.2.8'
implementation 'cn.jiguang.sdk.plugin:meizu:4.2.8'
implementation 'cn.jiguang.sdk.plugin:huawei:4.2.8'
implementation 'com.huawei.agconnect:agconnect-core:1.5.2.300'
implementation fileTree(dir: 'libs', include: ['*.jar', '*.arr'])
}
apply plugin: 'com.huawei.agconnect'
内容替换
华为推送比较特殊,需要修改项目级别的build.gradle
,另外仓库地址也要修改,即:
repositories.gradle
添加华为的仓库地址
ext.repos = {
google()
mavenCentral()
maven { url 'https://developer.huawei.com/repo/' }
}
build.gradle
也要添加buildscript
依赖插件
buildscript {
apply from: 'CordovaLib/cordova.gradle'
apply from: 'repositories.gradle'
repositories repos
dependencies {
classpath 'com.huawei.agconnect:agcp:1.5.2.300'
// 其他依赖
}
}
编写hook文件
这里hook
文件放到hooks目录
下面的after_platform_add
目录下,这个目录名自己定义即可,没有要求,文件名也可以自定义,这里起名AndroidPlatformInit.js
主要作用是把刚才的android_custom
下的文件复制到platforms/android/app
目录下,另外就是修改部分构建文件内容,内容参考:
另外针对华为推送需要修改项目级build.gradle以及repositories.gradle,使用正则表达式来替换
const path = require("path");
const fs = require("fs");
/**
* 从fromDir复制文件到toDir
* @param fromDir
* @param toDir
*/
function copyFiles(fromDir, toDir) {
var arr = fs.readdirSync(fromDir);
arr.forEach(function (item) {
var fromPath = path.join(fromDir, item);
var toPath = path.join(toDir, item);
var file = fs.lstatSync(fromPath);
if (file.isDirectory()) {
copyFiles(fromPath, toPath)
} else {
console.log('Copy ' + fromPath + ' to ' + toPath);
fs.createReadStream(fromPath)
.pipe(fs.createWriteStream(toPath));
}
});
}
/**
* 读取文件内容,然后替换部分内容后写回
* @param file
* @param callback
*/
function replaceContents(file, callback) {
fs.readFile(file, 'utf8', function (err, data) {
if (err) throw err;
data = callback(data);
fs.writeFile(file, data, 'utf8', writeErr => {
if (err) throw err;
console.log(file, 'replace success.');
});
});
}
/**
* 一些自定义操作
* @param ctx
*/
module.exports = function (ctx) {
console.log('======================android init hook==========================')
var rootDir = ctx.opts.projectRoot;
var androidCustomDir = path.join(rootDir, 'android_custom');
var androidAppDir = path.join(rootDir, 'platforms/android/app');
copyFiles(androidCustomDir, androidAppDir);
var projectRepositoriesGradleFile = path.join(rootDir, 'platforms/android/repositories.gradle');
var appRepositoriesGradleFile = path.join(rootDir, 'platforms/android/app/repositories.gradle');
// 华为的repository
var huaweiRepository = data => data.replace(/(mavenCentral\(\))/, '$1\n\tmaven { url \'https://developer.huawei.com/repo/\' }');
replaceContents(projectRepositoriesGradleFile, huaweiRepository)
replaceContents(appRepositoriesGradleFile, huaweiRepository)
// 华为的build插件
var projectBuildGradleFile = path.join(rootDir, 'platforms/android/build.gradle');
replaceContents(projectBuildGradleFile, data => data.replace(/(dependencies {)/, '$1\n\t\tclasspath \'com.huawei.agconnect:agcp:1.5.2.300\''))
}
配置hook
hook
配置文档:https://cordova.apache.org/docs/en/latest/guide/appdev/hooks/index.html
编写好hook
文件之后,其实并不能自动生效,需要在config.xml
中配置,目前只在android
下有用,直接配置到android
平台的节点之下。
这里选择在platform
添加的时候执行操作,常用类型参考文档中的说明。
<platform name="android">
<hook type="after_platform_add" src="hooks/after_platform_add/AndroidPlatformInit.js"/>
</platform>
执行cordova platform add android
的时候可以看到正常执行了文件复制以及文件内容替换:

然后在实际运行的时候可以发现build-extras.gradle
文件也已经生效了。