zoukankan      html  css  js  c++  java
  • Android 定制化apk生成

    日常开发过程中,经常会遇到定制化的app,但所谓的定制化,往往只是更改其中的一部分数据,或者更改不一样的功能,那么一般的做法也就是所谓的多渠道打包。

    但是多渠道打包的缺点就是首先需要知道有多少渠道。如果增加了渠道,还需要手动编辑build.gradle配置,然后再次生成。

    其实我们所说的渠道一般指的是应用商店的渠道,大的应用商店屈指可数,所以直接配置多渠道打包,也未尝不可,新增加一个应用商店那就手动添加一次。应用商店这种基础服务,不会一天出现好多,基本在市场初期就已经奠定基础了。

    但是并不是所有app都会上架到应用商店的,有一些apk只能去固定的地方下载,特别是toB的app。

    比如,我们原来是做web端的服务,一开始做的是PC端的,然后又做了移动端H5。由于服务是sass服务,对于每个租户来说都有其固定域名,租户访问服务都去访问自己的域名。由于移动端H5体验并不是很好,一次开发应用就显示十分必要,那么怎么区分租户app呢?

    最简单的形式是给每个租户定制化app[比如更改生成app的名字等],假如我们现有100个租户,每天新增十个,那么我如何动态更改呢?

    手动更改太累了

    那么有没有什么办法,可以避免手动操作呢?

    使用gradle,我们可以在build.gradle中编辑

    android {
        compileSdkVersion 28
        buildToolsVersion "29.0.0"
        defaultConfig {
            applicationId "cn.kanyun.tenant"
            minSdkVersion 24
            targetSdkVersion 28
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
            flavorDimensions "default"
    
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
                buildConfigField "String", "BASE_URL", APP_DYM_URL
            }
            debug {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    //            buildConfigField可以增加自动生成的BuildConfig类的变量
                buildConfigField "String", "BASE_URL", APP_DYM_URL
            }
        }
    
        productFlavors {
    //        WUMEI{
    //            applicationId "wumei.kanyun.cn"
    //            manifestPlaceholders=[app_name:"物美"]
    //        }
    //        SUNING{
    //            applicationId "suning.kanyun.cn"
    //            manifestPlaceholders=[app_name:"苏宁"]
    //        }
    
            dym {
                applicationId APP_DYM_ID
                manifestPlaceholders = [app_name: APP_DYM_NAME]
            }
        }
    }

    我们通过编辑其中的 productFlavors 和 buildTypes 就可以了

    上述就是所谓的多渠道打包

    我们所要做的就是在多渠道打包中添加点别的东西

    注意 标黄 的部分,那个部分定义的是变量

    那么这个变量定义在哪里呢?

    其定义在 gradle.properties 文件中

    配置了这些变量,就可以在build.gradle中就可以读取到了。

    那么当有新租户来的时候,只需要后台修改gradle.properties文件,然后运行构建脚本就可以生成apk了。

    但是这算是全部了吗?

    并不是这样的。

    这样其实也就定制了app的名字而已。

    前面说过由于我们的服务是sass服务,每个租户都有其固定域名,因此每个app发出的请求都有其固定前缀。

    我使用的是 Retrofit 框架

            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(Constant.BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create()) //设置使用Gson解析(记得加入依赖)
                    .build();

    可以看到 baseUrl() 方法,里面就是固定的前缀。

    那么问题就是如果让读取到gradle.properties中配置的 固定前缀呢(其实也就是租户域名) ,打包好的apk是没有gradle.properties的。

    那么只有一个可能,那就是在打包时,就将 固定前缀 赋值到  Constant.BASE_URL  

    来看Constant类

    public class Constant {
    
        public static final String BASE_URL = BuildConfig.BASE_URL;
    }

    这个类只有一行代码,可以看到 有一个 BuildConfig 类,

    这个类是哪里来的呢?我自己并没有定义过这个类

    来看看这个类的定义

    可以看到这类中的部分字段的值,就是之前在gradle.properties中定义的。

    那么这个BuildConfig这个类是哪里来的呢?

    实际上这个BuildConfig 类是自动生成的类,类似于R.class

    这个类是根据build.gradle配置文件自动生成的。生成后不能修改,只能修改配置文件。

    其中最重要的就是 需要修改 buildTypes 下的 buildConfigField 配置。

    关于这个类,可以查看  https://www.jianshu.com/p/274c9d95cf76

    总之,通过修改,我们终于可以实现定制化打包了。

    现在我们的服务更加完善了,用户填写了一些基础信息并注册完成后,后台通过CI/CD 下载app源码 -> 根据用户信息修改gradle.properties文件 -> 构建生成 等一系列操作 。之后我们就会直接给用户生成定制化的app下载链接,是不是更方便了。

  • 相关阅读:
    [SHOI2015]脑洞治疗仪
    [SDOI2016]数字配对
    [SDOI2019]快速查询
    [HNOI2019]JOJO
    [TJOI2019]甲苯先生和大中锋的字符串
    [CQOI2017]老C的方块
    [CQOI2017] 小Q的表格
    [SHOI2012] 火柴游戏
    板子
    自我介绍
  • 原文地址:https://www.cnblogs.com/kanyun/p/12887442.html
Copyright © 2011-2022 走看看