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

ok,是我,又是我。主要还是将一天中模糊的知识点进行汇总处理。

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

正文

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

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

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

BuildConfig

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

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

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

aidl 复制代码
android.defaults.buildfeatures.buildconfig=true

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

AndroidMainifest中的meta-data

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

aidl 复制代码
        <meta-data android:name="my_demo" android:value="${my_demo}"/>
        <meta-data android:name="my_demo_1" android:value="${my_demo_1}"/>

同样在 defaultConfig 中添加:

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

然后是获取meta-data的值:

aidl 复制代码
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中添加。

aidl 复制代码
        // 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项目中非常重要的配置项,可以根据需要灵活配置代码和资源的放置位置。

aidl 复制代码
    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

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

java 复制代码
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。所以:

aidl 复制代码
    // 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 :

aidl 复制代码
flavorDimensionList.apply {
        add("channel")
        add("cpu")
    }

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

aidl 复制代码
    applicationVariants.configureEach {
        resValue("color","my_demo6","#FFFFFFFF")
    }

sourceSets

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

aidl 复制代码
    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()的意思是这个可以被执行。只要可以执行到那个闭包中,那么具体实现就是想象空间了。嗯,整体来说还是蛮简单的,主要还是扩充认知,遇到了可以多一种选择罢了。

嗯,今天又没有卡12点,完美。

相关推荐
CYRUS STUDIO12 分钟前
ARM64汇编寻址、汇编指令、指令编码方式
android·汇编·arm开发·arm·arm64
weixin_449310841 小时前
高效集成:聚水潭采购数据同步到MySQL
android·数据库·mysql
Zender Han1 小时前
Flutter自定义矩形进度条实现详解
android·flutter·ios
白乐天_n3 小时前
adb:Android调试桥
android·adb
姑苏风7 小时前
《Kotlin实战》-附录
android·开发语言·kotlin
数据猎手小k10 小时前
AndroidLab:一个系统化的Android代理框架,包含操作环境和可复现的基准测试,支持大型语言模型和多模态模型。
android·人工智能·机器学习·语言模型
你的小1011 小时前
JavaWeb项目-----博客系统
android
风和先行11 小时前
adb 命令查看设备存储占用情况
android·adb
AaVictory.12 小时前
Android 开发 Java中 list实现 按照时间格式 yyyy-MM-dd HH:mm 顺序
android·java·list
似霰13 小时前
安卓智能指针sp、wp、RefBase浅析
android·c++·binder