Cordova自定义Android配置build.gradle

最近在给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 named build-extras.gradle. This file will be included by the main build.gradle when present. This file must be placed in the app 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 the before_build hook.

文档提到新建一个名叫build-extras.gradle的文件,并放到<your-project>/platforms/android/app文件夹中,这样就会自动使用上build-extras.gradle中定义的配置项了,因此我们可以在外面新建好该文件,然后复制到指定目录就可以了。

参考目录结构,新建一个android_custom目录,把需要复制到android平台下面的数据放到该文件夹下面,截图里的arrOPPO推送需要的依赖文件。

image-20220321114639973

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的时候可以看到正常执行了文件复制以及文件内容替换:

image-20220318151937644

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

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇