android 一套代码多用 以及 多套代码用于一个项目

文章关键字 productFlavors

目前在项目中遇到了这样一种状况,公司的产品须要在不一样的机子(本身产品)上进行运行,有的是正常手机 有的是没有显示屏的手机,须要另外作处理。那么如今问题来了,总不可能一个产品一个项目把,那么咱们就能够经过productflavors进行代码多用android

项目使用mvp架构 demo也是以此为前提

第一种状况,代码不变,素材变化

举一个极端的例子,你家的app卖不出,别人来代理你家的app,说图标要换成他家的,那么你怎么办?总不可能直接拿项目改把,万一又说不要你家app了呢?(开个玩笑)git

步骤: 先将android studio的目录结构改为project github

image.png

在与main同级下新建一个目录 我这里叫seller bash

image.png
而且根据main目录的目录结构(必定要同样),新建res 新建values 新建strings.xml
image.png
并将原来的appname 在后面加上111

tips1:这里说明一下,在res目录下的替换都是批量替换,在main目录的strings.xml里面确定不止一个strings,咱们在seller的strings.xml下新建一个appname 并更改了值 那么只有这个appname会被替换 其余的仍是原封不动的使用main的东西 tips2:其余同理,只要是在res目录下,都是批量替换(名字必定要同样 不管是string 仍是图片)架构

在替换以前 咱们还须要作一些事情,就是声明 在gradle文件里面 app

image.png
新增一个productFlavors 里面声明一个seller

productFlavors {
        seller {
        }
    }
复制代码

gradle sync以后 在build Variants里面就能够看到不一样的项目了 gradle

image.png

image.png

你可能会说 如今不就只剩一个了么,想用原来的代码不想用seller怎么办? 笑哭.jpg 新增一个就好 ui

image.png
新增一个空的origin

image.png
声明一下
image.png

打包的时候你能够同时打两个包 this

image.png

image.png

在build Variants里面的选项的做用:你选择哪一个,运行的时候(debug run)就运行哪一个版本 以上就是素材的替换google

第二种状况代码的替换

可能某一个部分的机器须要另外的新增的代码 并且与原来的代码区别仍是蛮大的 那么咱们能够进行代码的替换

tips1:代码的替换并非部分替换 而是文件的替换(例如一个mainActivity的替换,而不是mainActivity的某个代码片断的替换)

tips2:要替换的代码的那个文件不能存在于main文件夹内

如今 咱们在seller下新建同样的代码结构

image.png
并把MainActivity文件复制过来

image.png
并将Build Variant设置成sellerdebug

image.png
你会发现报错 因此说替换代码的时候main 文件夹内不能存在那个文件

如今将origin也复制一遍代码结构 而且将main文件夹内的删除

image.png
再也不报错

Tips:目前Build Variant是sellerdebug 因此seller下面的文件夹和main文件夹是有颜色的 可是origin没有,侧面说明android studio仍是挺智能的

以上就是代码的替换 只要你你运行那个分支你就会运行哪里的代码(没有替换的代码会用main文件夹的)

一些使用心得:若是只是小部分代码须要替换 最后仍是在main里面if else修改 比较方便 否则你就要维护两套代码 使用mvp分层的话 能够尽可能减小文件的替换 维护更少的代码!!!

第一二种状况能够混用

字符串的替换

若是你在seller中使用一个ip origin使用一个ip 怎么办

productFlavors {
        seller {
            buildConfigField("String", "URL", '"www.baidu.com"')
        }
        origin{
            buildConfigField("String", "URL", '"www.google.com"')
        }
    }
复制代码

使用buildConfig字段

String ip = BuildConfig.URL;
复制代码

这样这个ip在seller下是baidu 在origin下是google 是自动的

此外 也能够在debugrelease下使用

buildTypes {
        debug{
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            buildConfigField("String", "URL", '"www.baidu.com"')
        }
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            buildConfigField("String", "URL", '"www.google.com"')
        }
    }
复制代码

项目的判断

if (BuildConfig.FLAVOR.equals("seller")) {
            //// TODO: 2017/12/7  
        }
复制代码

使用flavor字段能够判断运行的是哪一个分支 而后进行小范围的代码的if else

项目的compile

例如 seller下使用腾讯的sdk 可是origin的使用百度的sdk 难道打包就须要打包两个sdk???

image.png

举个例子 使用分支的名字加上Compile就能够只在seller项目中compile这个东东

可是这样有个问题 若是你在同一套代码里面作了if else判断 若是在某个分支里面没有compile这个包 那么可能会报错

//举个例子:demo例子
//若是在seller项目中没有compile tx的sdk 那么编译的时候会报错 说没有找到tx sdk这个类
if(flag){
  TXSdk.init(this)
}else{
  BaiduSdk,init(this)
}
复制代码

ui同样的状况下 新增代码逻辑

在个人项目中 有一台手机是没有屏幕的 可是有一个lcd屏 因此我须要新增逻辑 进行处理 假设这个没有屏幕的手机是seller项目

seller项目须要compile一个jar包这个jar包很大 由于我是sellerCompile的 在origin中是没有的 因此我不能在main的代码中写入关于这个jar的代码 否则origin就编译不起来

那么我是怎么办的呢?

image.png

我新增一个receiver 和一个service 经过发intent的方式 若是是seller项目天然能够收到intent 而且使用jar包的类进行处理(使用jar包的代码在seller分支里面 而不是在main里面) 就没有问题,若是是origin项目 不会有receiver会收到这个intent 而后就不会处理

因此我是经过receiver进行中转处理的

以上就是我在项目中遇到的一些问题 以及productFlavor的一些使用 固然 productFlavor还有其余的一些用法 你们能够本身去了解一下

项目的demo(只有结构哈):https://github.com/Lemniscate317/ProductFlavorsDemo

相关文章
相关标签/搜索