简单的实现下通过gradle配置设置Android属性

早上,这个砖来一个一个需求,老板要求在版本号上面整一个打包日期,也没有要求太详细,就精确到天就好。emmm? 这个明显是不能手动改的,结合物理经验,无论是手动打包还是配置打包脚本,都需要基于gradle project,所以,这个方向就很明确了,这个写到build.gradle里面。那么如何整呢?

正文

我们先来整业务诉求,诉求很简单,每次gradle执行的时候,就存一个值到Android里面,方向有3个,

  • 往buildConfig中添加一个属性。
  • 往 AndroidMainifest 文件里面丢一个meta-data
  • 或者往resources 里面添加一个我们没有定义的 name

那么就开整,为了简单,那就直接写在 defaultConfig 闭包中。

BuildConfig

        var format= DateTimeFormatter.ofPattern("yyyy-MM-dd").format(LocalDate.now())
        buildConfigField("String","myName","\"${format}\"")

可以看到,上面的代码的逻辑很简单,往buildConfig 中添加一个field,名称为myName,类型是String,值是格式化后的当前日期。

如果报错了,提示需要开启权限,那就在项目的gradle.properties中添加

android.defaults.buildfeatures.buildconfig=true

先make project。调用的时候就直接BUildConfig.myName就可以了。 如果添加其他类型也是类似逻辑。

AndroidMainifest中的meta-data

首先我们需要先定义几个meta-data在AndroidManifest 中。

        <meta-data android:name="my_demo" android:value="${my_demo}"/>
        <meta-data android:name="my_demo_1" android:value="${my_demo_1}"/>

同样在 defaultConfig 中添加:

        // 写法1 
        manifestPlaceholders.put("my_demo","\"${format}\"")
        // 写法2,这个其实也是往manifestPlaceholders 这个map里面丢。
        addManifestPlaceholders(Map.of("my_demo_1","my_demo2"))

然后是获取meta-data的值:

val  info=packageManager.getApplicationInfo(
            packageName, PackageManager.GET_META_DATA
        )
        info.metaData.keySet().forEach{
            LogUtils.e(it+"  ${info.metaData.get(it)}")
        }

可以看到ContextWrapper也有一个getApplicationInfo。但是这个获取到的metaData是空。所以还是得通过GET_META_DATA 获取。

通过添加res的方式

这个有一个前提是,定义的res的name及其type没有被定义。还是在defaultConfig中添加。

        // string
        resValue("string","my_demo3","${format}")
        // boolean
        resValue("bool","my_demo4","true")
        // integer
        resValue("integer","my_demo5","5")
        // color
        resValue("color","my_demo6","#FFFFFFFF")

这个设置的字段必须是没有定义在res下面的,重新make project 在build/res/resValues/debug/values/gradleResValues.xml 就可以看到设置成功的内容了。 通常来说,值都应该用双引号保存。

其他方案

其他方案上来说,可能就是生成文件或者生成class的区别了。 生成文件,然后通过gradle 脚本复制到assets 目录下。生成的class 就需要放到指定的源码路径中了。

当然了也可以设置资源和class源码所在路径,那么就可以用到sourceSets。 在Android项目中,通过sourceSets可以配置代码和资源的放置位置。

sourceSets中的属性有:

  • java:指定Java代码的目录。
  • assets:指定资产文件的目录。
  • aidl:指定AIDL文件的目录。
  • jni:指定JNI文件的目录。
  • jniLibs:指定JNI库的目录。
  • manifest:指定清单文件的目录。
  • renderscript:指定RenderScript文件的目录。
  • res:指定资源文件的目录。
  • resources:指定资源文件的目录,与res功能相同。

除了上述属性外,sourceSets还可以通过setRoot(String path)方法,来显式指定特定的文件和目录。例如,如果在sourceSets中有多个目录,可以使用setRoot方法来设置根目录。 总之,sourceSets是Android项目中非常重要的配置项,可以根据需要灵活配置代码和资源的放置位置。

    sourceSets {
        getByName("main"){
            println( jniLibs)
            println( java)
            println( assets)
            println( aidl)
            println( jni)
            println( jniLibs)
            println( manifest)
            println( renderscript)
            println( res)
            println( resources)
        }
        // getByName(main) 和下面这种写法是一致的。
        main {
            println( jniLibs)
            println( java)
            println( assets)
            println( aidl)
            println( jni)
            println( jniLibs)
            println( manifest)
            println( renderscript)
            println( res)
            println( resources)
        }
    }

扩展:渠道、马甲或多环境

既然都写到这里了,感觉要不把马甲包和多环境的配置一起整了吧。上面的知识很多时候都是整马甲包或者多环境配置来着。像今天这种小众的需求还是很少的。

那么这种差异化的需求,通常有两种方式:

  • 一种是整多个 buildType
  • 一种是整多个 productFlavors
buildType

通常而言,多网络环境用这个挺多的。写法有很简单:

buildTypes {
    release {
        resValue("color","my_demo8","#FFFFFFFF")
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
    debug {
        resValue("color","my_demo9","#FFFFFFFF")
        signingConfig signingConfigs.debug
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
    text {
        resValue("color","my_demo6","#FFFFFFFF")
        signingConfig signingConfigs.debug
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
}

基于release或者debug 复制一个即可,然后在里面配置参数。

productFlavors

通常而言,这个主要是做马甲包,渠道包多一些,因为涉及到不同的目的切换不同的埋点,资源,cpu架构等等。 kotlin dsl 和groovy dsl 写法没有多少区别。都是基于flavorDimensions。所以:

    // groovy 写法
    // 方式1
    //flavorDimensions.flavorDimensions.add("cpu")
    //flavorDimensions.flavorDimensions.add("channel")
    // 方式2
    flavorDimensions("cpu","channel")
    productFlavors {
        create("baidu"){
            dimension="channel"
        }
        create("x86"){
            dimension="cpu"
        }
    }

kotlin 设置 flavorDimensionList :

flavorDimensionList.apply {
        add("channel")
        add("cpu")
    }

当然了,我们运行一个程序都需要选择以varinat 所以,我们可以基于varints统一配置固定的参数:

    applicationVariants.configureEach {
        resValue("color","my_demo6","#FFFFFFFF")
    }

sourceSets

既然每次选择都会选择一个variant,所以sourceSets里面就可以拿到flavor自己设置。例如:

    sourceSets {
        main {
            println( jniLibs)
            println( java)
            println( assets)
            println( aidl)
            println( jni)
            println( jniLibs)
            println( manifest)
            println( renderscript)
            println( res)
            println( resources)
        }
        baidu{
            println("baidu:" +java)
        }
    }

总结

可以看到上面很多printlin,写printlin()的意思是这个可以被执行。只要可以执行到那个闭包中,那么具体实现就是想象空间了。嗯,整体来说还是蛮简单的,主要还是扩充认知,遇到了可以多一种选择罢了。

最后

如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
img
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

欢迎大家一键三连支持,若需要文中资料,直接扫描文末CSDN官方认证微信卡片免费领取↓↓↓(文末还有ChatGPT机器人小福利哦,大家千万不要错过)

PS:群里还设有ChatGPT机器人,可以解答大家在工作上或者是技术上的问题

图片

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值