Android-Gradle-productFlavor多风味打包
Posted 普通网友
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android-Gradle-productFlavor多风味打包相关的知识,希望对你有一定的参考价值。
享学课堂诚邀作者:周周
转载请声明出处!
前言
手把手讲解系列文章,是我写给各位看官,也是写给我自己的。
文章可能过分详细,但是这是为了帮助到尽量多的人,毕竟工作5,6年,不能老吸血,也到了回馈开源的时候.
这个系列的文章:
1、用通俗易懂的讲解方式,讲解一门技术的实用价值
2、详细书写源码的追踪,源码截图,绘制类的结构图,尽量详细地解释原理的探索过程
3、提供Github 的 可运行的Demo工程,但是我所提供代码,更多是提供思路,抛砖引玉,请酌情cv
4、集合整理原理探索过程中的一些坑,或者demo的运行过程中的注意事项
5、用gif图,最直观地展示demo运行效果如果觉得细节太细,直接跳过看结论即可。
本人能力有限,如若发现描述不当之处,欢迎留言批评指正。
学到老活到老,路漫漫其修远兮。与众君共勉 !
正文大纲
1. gradle是什么
2. groovy语言的特性以及它和java的关系
3. 为什么你的apk打包这么慢
4. 如何利用gradle编程解决工作中的实际问题
5. gradle的高级用法(gradle多渠道快速打包插件)
承接上文【android Gradle(1) 概念及基础】https://www.jianshu.com/p/c36cd9aa2724
4. 如何利用gradle编程解决工作中的实际问题
前置知识
前面提到了,gradle可以编写代码逻辑。那么既然是可以自定义逻辑,那么我们在熟悉gradle编程规范之后,能把我们自己的逻辑,嵌入到 gradle的编译打包过程中去。
但是在此之前,有必要了解一下gradle的打包流程
上图中,把gradle的整体编译过程分为了3个阶段:
初始化=>配置=>执行
初始化:执行的是setting.gradle
文件
配置:执行的是 所有的build.gradle
文件
执行: 到了这里,系统中就生成了一个有序状态图(taskGraph
),系统按照这个taskGraph
去执行所有的task,完成打包。
而上图中,还有3个 Hook 钩子,这意味着,我们可以通过gradle
编程手段,自己定义3个hook
,来干涉编译打包的过程,达成我们自己的目的。钩子同样也会进入到有序状态图(taskGraph),随着打包的过程一起执行。
这里涉及到一个task的概念,它是gradle中的一个重要概念,代表一个任务。
如何查看当前环境有哪些task可用?
两种方式,
图形化界面去查看,你可以直接双击某个task去执行:
命令行去查看:
gradlew tasks
回车
你也可以通过命令行去执行某个task,比如说:
我要 安装一个debug版本的apk到设备上:
gradlew installDebug
回车.
我们加入自己的逻辑,一般都会以task为单位去执行。
要编程,除了要了解语法之外,还需要了解 gradle的api架构层级关系,请到gradle的下载根目录,找到下面的目录:
C:\\Users\\adminstrator\\.gradle\\wrapper\\dists\\gradle-4.4-all\\9br9xq1tocpiv8o6njlyu5op1\\gradle-4.4\\src\\core-api\\org\\gradle\\api
C:\\Users\\adminstrator\\.gradle\\wrapper\\dists\\gradle-5.1.1-all\\97z1ksx6lirer3kbvdnh7jtjg\\gradle-5.1.1\\src\\core-api\\org\\gradle\\api
这里应该包含了我们gradle编程需要用到的所有类。
官方参考文档
除此之外,了解了代码框架之外,我们还需要知道 gradle里面一些配置应该参考的官方文档,这里给出:
http://google.github.io/android-gradle-dsl/current/
上主菜
推荐一种沟通发言说话面试的神级技巧STAR法则,按照 situation 情境 ,task 任务 ,action 行动,result 结果 的顺序来描述一件事,条理清楚,有理有据,说服力强。
situation 情境
国内android大环境大家心里都有数,各大厂家各自为政,经常互掐,应用市场也是门派林立,各自有各自的要求。于是,老板要求,我们开发的app能够快速打出 对应的应用市场的apk,发布到对应的应用市场,并且,老板还想玩点骚操作,经常给app换点主题颜色什么的,今天红色, 下个月白色…虽然心里MMP,但是脸上还是要笑嘻嘻的去跟老板说“包在我身上”…
task 任务
上面的情境中,我们分析出老板的2个核心需求,app代码开发完毕之后,我们要在打包的时候设定特殊的参数,让app在不同的应用市场下的表现有所差异,达到该应用市场的要求。老板的骚操作??? 换主题?同样,给定特殊参数,打包的时候自主选择,打出特定主题颜色的apk.
action行动
定下了目标,那么自然需要我们付诸行动。现在祭出 干货:满足多渠道,多主题混合打包的**androidStudio Demo工程**
关键部分解读:
1.新建 flavor.gradle 文件,内容编辑如下:
android
//定义多渠道配置
flavorDimensions "channel", "theme" // 我要求有两种维度,一个是 渠道,一个是 主题
file("./channel.txt").readLines().each
channel ->
println(channel)
productFlavors.create(channel,
dimension 'channel'
manifestPlaceholders = [channelName: channel]
)
file("./theme.txt").readLines().each
theme ->
println(theme)
productFlavors.create(theme,
dimension 'theme'
manifestPlaceholders = [themeName: theme]
)
同时,建立2个txt
,channel.txt
配置 渠道
,theme.txt
配置 主题
疑难解答
这部分涉及 核心gradle代码,有必要讲解一下:
android : android工程的下gradle代码的"根目录", 与android打包直接相关的配置,必须放在android的闭包里。
flavorDimensions “channel”, “theme” flavor == “风味”,dimensions="维度"复数
声明所有的 flavor “风味维度”, 先声明,而后再进行配置。这一句的意思是:下面的配置,会涉及到2个维度的打包风味,一个维度是channel,一个维度是theme,如果channel维度下有4
个配置,theme维度下有3
个配置,那么 打包风味的总数就是3x4=12
种
file("./channel.txt").readLines().each 这是gradle里面的文件IO流的写法,语法简单易懂,逐行读取channel.txt文件,然后each遍历 … 里面的闭包写法不需要我再解释了吧…
println(channel) gradle的打印,这个打印会在android的run栏目里面看到
productFlavors.create(theme,
dimension ‘theme’
manifestPlaceholders = [theme: theme]
)
productFlavors 这是gradle官方提供的专门解决多风味打包的库。
它的create
方法有2个参数,一个是风味的名字,一个是闭包,闭包里面可以自行编辑该风味下的特性。
dimension ‘theme’ 当前风味所处的维度是theme维度
,表示主题风格.
manifestPlaceholders = [themeName: theme]manifestPlaceholders
是定义 android工程中manifest.xml的占位符对应的具体值.
(占位符?
请继续观下文)。
2. AndroidManifest.xml 中定义meta-data
<application ...>
...
<!-- 预定义一些可变参数,打包的时候会根据配置,有所变化 -->
<meta-data
android:name="CHANNEL"
android:value="$channelName" />
<meta-data
android:name="THEME"
android:value="$themeName" />
</application>
3. 在android的java代码中,取得meta-data的具体值,并且将它用到业务代码中去,让app在打不同包的时候,产生不同的特性(UI特性,业务特性).
public class MainActivity extends AppCompatActivity
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tvCurTheme = findViewById(R.id.curTheme);
TextView tvCurChannel = findViewById(R.id.curChannel);
getMetaData();
tvCurTheme.setText(theme);
tvCurChannel.setText(channel);
String channel;
String theme;
/**
* 从manifest中读取出metadata
*/
private void getMetaData()
PackageManager pm = getPackageManager();
try
ApplicationInfo appInfo = pm.getApplicationInfo(BuildConfig.APPLICATION_ID, PackageManager.GET_META_DATA);
Bundle bd = appInfo.metaData;
channel = bd.getString("CHANNEL");
theme = bd.getString("THEME");
catch (PackageManager.NameNotFoundException e)
e.printStackTrace();
关键代码就是 getMetaData()
方法.
核心代码简单解读:
PackageManager : 与android打包相关的东西,基本上都被管理在PackageManager里面,它是一个跨进程的AIDL函数调用:
@Override
public PackageManager getPackageManager()
if (mPackageManager != null)
return mPackageManager;
IPackageManager pm = ActivityThread.getPackageManager();
if (pm != null)
// Doesn't matter if we make more than one instance.
return (mPackageManager = new ApplicationPackageManager(this, pm));
return null;
ApplicationInfo appInfo = pm.getApplicationInfo(…) 拿到了pm之后,用这个函数来获得当前app的应用信息,也就是 androidManifest.xml中application标签内的所有信息,包括我们定义的meta-data.
Bundle bd = appInfo.metaData; metaData是一个android 中实现了 Parcelable 接口的键值对的封装,其取值方式也是bd.getString("CHANNEL");
三步走之后,我们编译同步一下gradle.
踩坑教训:gradle编程,在androidStudio上非常别扭,有时候没有代码提示,有时候代码提示不全,有时候提示的是错的,总之,不要太相信as… 如果发现编译报错,要从错误日志去查找可能原因。
这也是我如此详尽解释每一句代码的原因,对于初学者而言,任何一个低级错误都有可能让你抓狂好一阵子,网上太多这种不明不白的博客,让人看了不如不看,更有好多都是错误的,所以我给出了可运行的Demo地址:androidStudio Demo工程 供读者调试研究。
result 结果
一顿操作猛如虎,现在来验证我们的劳动成果了:
两种方式,命令行方式 或者 图形界面方式。
先说命令行
gradlew tasks 查看当前可以使用的所有task
gradlew assembleHuaweiBlack
生成了这两个包,一个debug,一个realease(如果只需要release,可以用gradlew assembleHuaweiBlackRelease
)
adb install -r C:\\Users\\adminstrator\\AndroidStudioProjects\\GradleStudy1021\\app\\build\\outputs\\apk\\huaweiBlack
\\debug\\app-huawei-black-debug.apk 安装刚才生成的debug包,装好之后打开一看:
还记得刚才打包的是什么吗?huawei的黑色风格!
再说图形界面
(一看就懂,不用我多BB了。。):
如果我双击这个:
duang!
打完收工!
事后总结
上文展示了 gradle在实际工作中 如何去解决 多风味打包的问题,但是这个仅仅是开端,实际工作比我们想的要更加复杂。gradle的学习,as的环境并不友好,但是毕竟as是主流,临时换一个ide又不划算。所以必须找到有效的学习方式,才能够保证学习效率。 最直接的,就是官方文档,http://google.github.io/android-gradle-dsl/current/ ,它可以让你对android工程中所有的gradle配置有完整的了解,并且随时查阅。
结语
本文比较基础,下一篇来点更刺激的,你们一定发现了,本文攻略虽然可以解决变态老板的多渠道,多主题打包的要求,但是,每一次打包,都会走一次完整的apk编译打包流程,如果1个包,要5分钟,那么10个包就将近一个小时了,而且,如果老板需要 多渠道,多主题,多语言…3个维度打包,那么耗费的时间将会成几何级数增长。我们作为android 高级开(码)发(农)要善于利用技术手段解决实际问题,下一篇文章将详解如何优雅,快速的打出我想要的 "风味"包!
请期待: Android Gradle(3) gradle插件V1签名多风味打包
线程、数据库、算法、JVM、分布式、微服务、框架、Spring相关知识
一线互联网P7面试集锦+各种大厂面试集锦
学习笔记以及面试真题解析
radle插件V1签名多风味打包
线程、数据库、算法、JVM、分布式、微服务、框架、Spring相关知识
[外链图片转存中…(img-Bea2WEyw-1623555802774)]
一线互联网P7面试集锦+各种大厂面试集锦
[外链图片转存中…(img-DR9HqQXk-1623555802775)]
学习笔记以及面试真题解析
以上是关于Android-Gradle-productFlavor多风味打包的主要内容,如果未能解决你的问题,请参考以下文章