一次代码,建立多次

前言

大家可能会有类似这样的需求:同一个APP发布不同的版本,修改里面的主题、icon、applicationId。这应该怎么弄呢?很多同学都是重新check一份工程直接修改的。但其实是不必要的,android studio 的gradle就可以帮我们做到。

1、Build Variants(构建变量)

让我们从一般的概念入手,构建变量。
gradle允许您定义多个构建变量定义的构建变体由一个特定的所有属性生成类型加入到一个特定的所有属性的 product flavors 里面。
Build variants, build types, product flavors?虽然有点陌生,让我们接下来一一了解一下。
a、build types
你已经在你的项目中使用了不同的构建类型。检查您的应用程序的build.gradle文件。一个名为:defaultConfig,当你创建一个新的项目自动设置了两个build types (构建类型)debug和release。如图所示:

image.png

所以这里咱们是可以切换debug和release类型的。

2、Product Flavors(产品偏好)

对于每一个调试类型(debug/release),可以指定不同的内容,也就是product favours,例如,如果你希望你的程序有付费版本和免费版本,这个两个(免费、付费)代表你应用程序的product flavors。
所以回到构建变量,这里我们生成4个构建变量:
a、freeDebug
b、paidDebug
c、freeRelease
d、paidRelease

例子

现在我们看看如果实现product flavors。
首先你需要一个product flavors在你的项目的build.gradle文件里面。


app-gradle-and-product-flavors.png

如果“同步工程与gradle文件”,


sync-project.png

那么你就会看到新的 build variants(构建变体)。


all-build-variants.png

在这里你可以添加特定于每个变体的属性。
例如,如果你希望能在同一个设备上安装应用程序的两种版本(免费、付费),或者你想在应用商店发布他们2个,那么你需要做的第一件事情就是来区分他们的包名。为此,你需要使用applicationId属性。

productFlavors {
  free{
       applicationId "antoniocappiello.com.buildvariantsexample.free"
  }
  paid{
       applicationId "antoniocappiello.com.buildvariantsexample.paid"
  }
}

Sync/Rebuild项目,以便使更改生效。
现在,你可以选择freeDebug和paidDebug在构建变量面板和设备上运行他们。
之后,你就会在设备上看到应用程序的两种变体,但你仍无法辨认他们,因为缺少了相关属性设置。

apps.png

一个快速的发放来区分是什么呢?就是改变启动图标。创建新的src目录,我们要区分product favours的名称,例如“免费”,这个新的目录也创建了"res/drawable"。而内绘制了一个新的图标,在这个例子中我们使用了默认的启动印有文字的“自由”。

launcher-free.png

通过重建,并再次运行这两个变体,你将会看到设备上有2个不同的应用程序。


launcher-2.png

在这里,你可以设置更多的样式属性,例如“主题”、“部分文本的颜色”

更改颜色.png
更换文本.png

通过再次运行freeDebug变体和paidDebug变体,你就可以清楚的看到他们之间的区别。

对比.png

除了这些审美的变化,你可能还希望有不同的功能,以适于每种变体。一个简单的方法来实现这一目标是通过将在运行时被读取的product flavors配置中定义的变量。例如用EXTRA_FEATURE变量做如下补充,你可以在你的应用程序中使用if-else来做简单的判断。

productFlavors {
  free{
         applicationId "antoniocappiello.com.buildvariantsexample.free"
         buildConfigField 'boolean', 'EXTRA_FEATURES', "false"
      }
   paid{
         applicationId "antoniocappiello.com.buildvariantsexample.paid"
         buildConfigField 'boolean', 'EXTRA_FEATURES', "true"
      }
}

public class MainActivity extends AppCompatActivity {
        private Toast basicToast;
        private Toast coolToast;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
        basicToast = Toast.makeText(this, "This is just a free app",Toast.LENGTH_SHORT);
        coolToast = Toast.makeText(this, "This is the paid app", Toast.LENGTH_SHORT); 
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener(){
              @Override
              public void onClick(View view) {
                  if(BuildConfig.EXTRA_FEATURES) {
                          executeCoolMethod();
             }else {
                  executeBasicMethod();
             }
          }
      });
   }
 
        private void executeBasicMethod() {
              basicToast.show();
        }
 
        private void executeCoolMethod() {
              coolToast.show();
        }
}
screen-shot-2015-10-21-at-23-48-34.png

当然你的代码应该还会需要其他类型变量,如“字符串”,比如“BaseUrl”

android {
...
defaultConfig {
...
}
 
productFlavors {
    free {
          applicationId "yourpackagename.free"
          buildConfigField 'boolean', 'EXTRA_FEATURES', "false"
          buildConfigField 'String', 'BaseUrl', '"www.baidu.com"';
     }
    paid {
          applicationId "yourpackagename.paid"
          buildConfigField 'boolean', 'EXTRA_FEATURES', "true"
          buildConfigField 'String', 'BaseUrl', '"www.google.com"';
    }
  }
}

product flavors 有更多的属性,这通常是结合defaultConfig的。你可能已经看到上面的gradle文件里面的元素了,当你创建一个新的项目时,这里是自动创建的。
当你在productFlavors使用这些属性时,他们将自动覆盖相同属性的值defaultConfig元素。
你已经看到了applicationId属性,它实际上市属于defaultConfig的元素,但在上面的例子中,我们已经在我们的productFlavors覆盖它。
如果你有兴趣了解更多的有关可用属性的defaultConfig,那么你可以在这里阅读官方文档:
https://developer.android.com/studio/build/index.html .

总结到目前为止,你所学到的现在可以:

  • 添加productFlavor配置您的gradle这个文件;
  • 覆盖现有的构建属性,如的applicationID
  • 像添加字符串和布尔自定义属性;
  • 安装在一个设备上相同的应用程序的两个不同的构建变体;
  • 自动改变的行为和你的应用程序从该是建立根据变种的外观和感觉。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容