大部分人都经历过高中,不难发现高考650分的人和450分的人书单基本上是一样的,这是为什么呢?

这往往并不是因为他们接触了更多的信息,而是因为他们处理信息的方式与众不同。他们往往善于整理信息,并且获得“系统化知识体系”。

写在前面的话

今天翻了翻自己之前的博客,发现上一篇还是在2017-01-12发的。不知不觉3个月就过去了,之间好像再也没有很系统的总结过东西了。仔细想想一年也没几个3个月,还是有点方的。

3个月说长不长,但也足够发生很多事情。比如我投身到了直播(YOLO)行业,开始接手前人(Piasy、promeG等等)的项目,之间曲折自不需多说。好在已经适应了现在的节奏,博客也会慢慢更新。

其实直播并没有想象中的那样复杂,概括的讲无非就是采集端(推流端)和观众端(拉流端)。然后再添加一些礼物系统、弹幕系统、聊天系统、人脸识别、游戏互动、连麦互动、美颜等功能使之丰满。

关于直播,我们暂且不进行深入讨论。今天我们来说一说Gradle相关的东西。可能好多人会有这样的感慨,为什么我看了那么多“Gradle从入门到精通”,仍然管理不好自己项目的构建呢?今天我们就来一起整理下Gradle相关的那些知识点,也许会有收获哦。

Gradle思维导图

为了方便梳理Gradle的知识点,我画了下面的思维导图,有不足的地方还望大家指出。其实这些点基本上每个都可以写一篇单独的博客来扩展,而且有很多已经总结的很好了,这里就不赘述了。

而关于我们为什么要用Gradle,Gradle能做什么这样的问题,弄清楚也是很有必要的。比较官方的说法是:Gradle使用易懂的DSL语法 ,将开发过程中需要的编译、构建、测试、打包以及部署工作,变得非常简单、而且方便重复使用。即Gradle可以从开发过程的各个环节来简化我们的开发。

Gradle实战

俗话说的好:Talk is cheap,show me the code。接下来我就抛砖引玉,分享下我们的Gradle是怎样配置的。

项目根目录下的build.gradle文件

// Top-level build file where you can add configuration options common to all sub-projects/modules.apply from: 'buildsystem/dependencies.gradle'buildscript {repositories {jcenter()}dependencies {apply from: 'buildsystem/dependencies.gradle'classpath "com.android.tools.build:gradle:$gradleAndroidVersion"classpath 'com.github.promeg:android-multi-channel-plugin:0.1' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files}
}task clean(type: Delete) {delete rootProject.buildDir
}

app下的build.gradle文件

import java.text.SimpleDateFormatimport static org.apache.tools.ant.taskdefs.condition.Os.FAMILY_WINDOWS
import static org.apache.tools.ant.taskdefs.condition.Os.isFamilyif (!testDevelopURC) {apply plugin: 'com.android.library'
} else {apply plugin: 'com.android.application'
}
apply plugin: 'android-multi-channel'def keyConfigPath
if (isFamily(FAMILY_WINDOWS)) {keyConfigPath = System.getenv('USERPROFILE') + File.separator + ".ssh" + File.separator +"androidKeystore.properties"
} else {keyConfigPath = System.getenv('HOME') + "/.ssh/androidKeystore.properties"
}
Properties props = new Properties()
if (new File(keyConfigPath).exists()) {props.load(new FileInputStream(file(keyConfigPath)))
}android {def rootDep = rootProject.extcompileSdkVersion rootDep.androidCompileSdkVersionbuildToolsVersion rootDep.androidBuildToolsVersiondefaultConfig {minSdkVersion rootDep.androidMinSdkVersionntargetSdkVersion rootDep.androidTargetSdkVersionversionCode rootDep.releaseVersionCodeversionName rootDep.releaseVersionNametestInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"multiDexEnabled truevectorDrawables.useSupportLibrary = trueif (!testDevelopURC) {applicationId "tv.yoloyolo.renlei.gradlepractice"} else {consumerProguardFiles 'proguard-rules.pro', 'proguard-fresco.pro'}buildConfigField "String", "API_BASE_URL", "\"https://api.test.base\""manifestPlaceholders = [EASEMOB_APPKEY: "publish#publish"]}lintOptions {abortOnError false}packagingOptions {exclude 'META-INF/LICENSE.txt'exclude 'LICENSE.txt'exclude 'META-INF/LICENSE'exclude 'META-INF/NOTICE'exclude 'META-INF/NOTICE.txt'exclude 'META-INF/services/javax.annotation.processing.Processor'exclude 'META-INF/rxjava.properties'}signingConfigs {release {storeFile file(props['keystore'])storePassword props['keystore.password']keyAlias "promegu"keyPassword props['key.password']}}dexOptions {maxProcessCount 8javaMaxHeapSize "6g"}testOptions.unitTests.all {testLogging {events 'passed', 'skipped', 'failed', 'standardOut', 'standardError'outputs.upToDateWhen { false }showStandardStreams = true}// configure the test JVM argumentsjvmArgs '-noverify'}aaptOptions {cruncherEnabled false}publishNonDefault trueproductFlavors {dev {ndk {abiFilter "armeabi"}buildConfigField "String", "API_BASE_URL", "\"https://api.test.base\""manifestPlaceholders = [EASEMOB_APPKEY: "test#test"]}production {ndk {abiFilter "armeabi"}// inherit from default config}}buildTypes {debug {minifyEnabled falsedebuggable trueext.enableCrashlytics = falsesigningConfig signingConfigs.release}release {minifyEnabled falsedebuggable falsesigningConfig signingConfigs.releaseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}}
}multiFlavors {prefix = "TEST_";def released = new SimpleDateFormat('yyyy-MM-dd').format(new Date())subfix = "_$released";defaultSigningConfig = android.signingConfigs.releasechannelConfig {production {childFlavors =["Tencent", "360", "Baidu", "Alibaba", "GFan", "Sogou","Lenovo", "XiaoMi", "Meizu", "OPPO", "Huawei", "GooglePlay"]}}
}dependencies {compile fileTree(dir: 'libs', include: ['*.jar'])androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {exclude group: 'com.android.support', module: 'support-annotations'})compile 'com.android.support:appcompat-v7:25.3.1'testCompile 'junit:junit:4.12'testCompile 'org.robolectric:shadows-support-v4:' + rootProject.ext.robolectricVersioncompile('com.github.promeg:android-multi-channel-plugin-lib:0.1') {exclude module: 'appcompat-v7'}
}

外部的dependencies.gradle文件

我在项目根目录创建了一个叫buildsystem的文件夹,dependencies.gradle文件放到了这个文件夹下。

allprojects {repositories {jcenter()}
}ext {androidBuildToolsVersion = '25.0.2'androidCompileSdkVersion = 25androidMinSdkVersionn = 15androidTargetSdkVersion = 25androidSupportSdkVersion = '25.1.0'gradleAndroidVersion = '2.2.3'releaseVersionCode = 1releaseVersionName = "1.0"robolectricVersion = '3.0'
}

项目根目录下的gradle.properties文件

# Project-wide Gradle settings.# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
#org.gradle.jvmargs=-Xmx1536m# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=trueorg.gradle.jvmargs=-Xmx8192m -XX\:MaxPermSize\=3072m
org.gradle.daemon=true
org.gradle.configureondemand=true
org.gradle.parallel=truetestDevelopURC=false

应用到的知识点

基本上就是这样了,这几个文件的配置是从YOLO项目简化而来的,不过不影响研究。接下来我们看下里边用到的点。由于具体每个点的实现网上好多已经介绍的很全面了,这里我只说下大概的点,具体大家可以自行google。后边我也会附上一些链接供大家参考。

依赖外部配置

如果我们的配置文件过大或者有需要复用的配置,可以考虑抽离成一个单独的文件,引入方式如下:

apply from: 'buildsystem/dependencies.gradle'

全局配置

Stack Overflow:How to define common android properties for all modules using gradle

ext {androidBuildToolsVersion = '25.0.2'androidCompileSdkVersion = 25androidMinSdkVersionn = 15androidTargetSdkVersion = 25androidSupportSdkVersion = '25.1.0'gradleAndroidVersion = '2.2.3'releaseVersionCode = 1releaseVersionName = "1.0"robolectricVersion = '3.0'
}

占位符

如果我们在manifest中定义了占位符的话,可以在module的build.gradle中可以将其进行赋值。

<meta-dataandroid:name="EASEMOB_APPKEY"android:value="${EASEMOB_APPKEY}" />manifestPlaceholders = [EASEMOB_APPKEY: "publish#publish"]

ProductFlavors

对于ProductFlavors,我们可以在Build->Select Build Variant…选择我们开发状态下使用的默认配置。

productFlavors {dev {ndk {abiFilter "armeabi"}buildConfigField "String", "API_BASE_URL", "\"https://api.test.base\""manifestPlaceholders = [EASEMOB_APPKEY: "test#test"]}production {ndk {abiFilter "armeabi"}// inherit from default config}
}

BuildTypes

Gradle官方文档:BuildType,这篇讲的是有BuildType有哪些可以配置东西。

debug {minifyEnabled falsedebuggable trueext.enableCrashlytics = falsesigningConfig signingConfigs.release}

BuildConfig

自定义BUILDCONFIG

buildConfigField "String", "API_BASE_URL", "\"https://api.test.base\""

dependencies

包括依赖的几种类型,以及如果解决依赖冲突。

Gradle官方文档:依赖项管理基础知识

Android官方文档:Add Build Dependencies

排除传递依赖

dependencies {compile fileTree(dir: 'libs', include: ['*.jar'])androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {exclude group: 'com.android.support', module: 'support-annotations'})compile 'com.android.support:appcompat-v7:25.3.1'testCompile 'junit:junit:4.12'testCompile 'org.robolectric:shadows-support-v4:' + rootProject.ext.robolectricVersioncompile('com.github.promeg:android-multi-channel-plugin-lib:0.1') {exclude module: 'appcompat-v7'}
}

签名

这里用到了一些Groovy中的语法,主要用来找到自己的androidKeystore.properties文件并从中读取配置。

Android官方文档:签署您的应用

def keyConfigPath
if (isFamily(FAMILY_WINDOWS)) {keyConfigPath = System.getenv('USERPROFILE') + File.separator + ".ssh" + File.separator +"androidKeystore.properties"
} else {keyConfigPath = System.getenv('HOME') + "/.ssh/androidKeystore.properties"
}
Properties props = new Properties()
if (new File(keyConfigPath).exists()) {props.load(new FileInputStream(file(keyConfigPath)))
}signingConfigs {release {storeFile file(props['keystore'])storePassword props['keystore.password']keyAlias "promegu"keyPassword props['key.password']}
}

各种options配置

Gradle官方文档:Android Plugin DSL Reference

packagingOptions {exclude 'META-INF/LICENSE.txt'exclude 'LICENSE.txt'exclude 'META-INF/LICENSE'exclude 'META-INF/NOTICE'exclude 'META-INF/NOTICE.txt'exclude 'META-INF/services/javax.annotation.processing.Processor'exclude 'META-INF/rxjava.properties'
}
dexOptions {maxProcessCount 8javaMaxHeapSize "6g"}testOptions.unitTests.all {testLogging {events 'passed', 'skipped', 'failed', 'standardOut', 'standardError'outputs.upToDateWhen { false }showStandardStreams = true}// configure the test JVM argumentsjvmArgs '-noverify'}aaptOptions {cruncherEnabled false}

多渠道打包

这个多渠道打包其实是之前同事自己写了一个Gradle插件。传送门。

当然如果你熟悉Groovy语法,也可以自己编写。编写Gradle插件。

multiFlavors {prefix = "TEST_";def released = new SimpleDateFormat('yyyy-MM-dd').format(new Date())subfix = "_$released";defaultSigningConfig = android.signingConfigs.releasechannelConfig {production {childFlavors =["Tencent", "360", "Baidu", "Alibaba", "GFan", "Sogou","Lenovo", "XiaoMi", "Meizu", "OPPO", "Huawei", "GooglePlay"]}}
}

加速编译

Android官方文档:优化你的编译速度

dexOptions {maxProcessCount 8javaMaxHeapSize "6g"}org.gradle.jvmargs=-Xmx8192m -XX\:MaxPermSize\=3072m
org.gradle.daemon=true
org.gradle.configureondemand=true
org.gradle.parallel=true

Other

除了上边提到的那些点之外,还有一些总结的比较好的链接。其实国内好多博客都大同小异,都参考自官方文档,所以推荐直接看官方文档。

  • 官方文档:Gradle Plugin User Guide
  • Gradle Plugin User Guide 翻译版
  • 官方文档:构建和运行您的应用
  • 官方文档:配置构建概览
  • 官方文档:配置构建变体
  • 官方文档:从命令行运行Gradle
  • 官方文档:设置应用的ID
  • Gradle构建最佳实践
  • Gradle配置最佳实践

结语

可能上边说的内容比较多,不过大家可以按需查看。而且工欲善其事,必先利其器。对于我们来说,学好Gradle无疑可以对开发提供很大的帮助,节省更多的时间。

感谢官方文档详细的教程,也感谢喜欢分享的那些朋友,如果上边链接有侵权的话,请告诉我,我会删掉。

Gradle的卖家秀和买家秀相关推荐

  1. 数据集标注工具_DeepFashion2数据集:87.3万对“买家秀-卖家秀”图像+海量标注

    内容首发于"迈微AI研习社"公众号 DeepFashion 是当前最大的时尚数据集,但它也有一些缺陷,使其与现实场景存在巨大差距.为此,本文作者提出了 DeepFashion2,其 ...

  2. 用AI说再见!“辣眼睛”的买家秀

    阿里妹导读:提起买家秀和卖家秀,相信大家脑中会立刻浮现出诸多画面.同一件衣服在不同人.光线.角度下,会呈现完全不同的状态.运营小二需从大量的买家秀中挑选出高质量的图片.如果单纯靠人工来完成,工作量过于 ...

  3. AI挖掘优质淘宝买家秀 再也不用担心辣眼睛了

    说到淘宝优质买家秀内容挖掘 必须从买家秀和卖家秀说起 我们总是能在卖家秀和买家秀中找到强烈反差 比如这样 这样 又或者这样 (图片来自网络) 买家秀和卖家秀对比这么一言难尽,那还怎么让运营小二们愉快地 ...

  4. 用AI说再见!“辣眼睛”的买家秀 1

    阿里妹导读:提起买家秀和卖家秀,相信大家脑中会立刻浮现出诸多画面.同一件衣服在不同人.光线.角度下,会呈现完全不同的状态.运营小二需从大量的买家秀中挑选出高质量的图片.如果单纯靠人工来完成,工作量过于 ...

  5. 用AI说再见!“辣眼睛”的买家秀 2

    阿里妹导读:提起买家秀和卖家秀,相信大家脑中会立刻浮现出诸多画面.同一件衣服在不同人.光线.角度下,会呈现完全不同的状态.运营小二需从大量的买家秀中挑选出高质量的图片.如果单纯靠人工来完成,工作量过于 ...

  6. 深度拆解:直播带货的现状与未来?

    直播带货的热度一路飙升,受到疫情影响,CEO们开始涌进直播间带货,更是炒热了人们的关注与讨论.本文笔者结合热点分享了自己关于直播带货的几点思考,对直播带货的未来进行了展望. 一场疫情,把直播带货推向了 ...

  7. 苹果wifi网速慢怎么办_所以,WiFi和4G到底哪个更耗电?

    来源 | 中科院物理所(ID:cas-iop) 编辑 | 椒盐猫巨烦 现代人行走江湖,必备三件法宝:手机,网络,充电宝. 即便在4G基站遍布各个旮旮角角的今天,当你带着心仪的人儿走进一家咖啡店,第一件 ...

  8. 9-Nagel-Schreckenberg交通流模型-公路堵车概率模型

    路面上有n辆车,以不同的速度向前行驶, 模拟堵车问题.有以下假设: 1.假设某辆车的当前速度是v. 2.若前方可见范围内没车,则它在下一秒的车速提高到v+1,直到达到规定的最高限速. 3.若前方有车, ...

  9. 为什么游戏模型不如原画好看?

    游戏已经成为每个人在业余时间放松的一种主要方式.要说目前最火的游戏,终端游戏肯定是英雄联盟.上线十几年,一直保持高热度,联赛如火如荼,新英雄新皮肤层出不穷. 而手游绝对非王者荣耀莫属,也是拥有自己的职 ...

最新文章

  1. Java JNI简单实现
  2. LabelImg操作及快捷键
  3. Windows7环境下用VirtualBox (5.1)上安装Ubuntu 17.10
  4. Linux入门笔记——文件操作命令2
  5. [已解决]fdfs-client-py==1.2.6安装失败
  6. 软件开发有哪些规范和标准_高品质、标准化——四维图新自动驾驶地图通过ASPICE CL2认证...
  7. 马斯克点赞中国新能源汽车产业,特斯拉加快中国超级充电网络布局
  8. MEMCACHE分布式算法(PHP)
  9. Linux的操作系统原理详解
  10. 软件观念革命:交互设计精髓_交互的学习与应用指南
  11. 记录:pycharm的强大之处之两个文件代码的比对
  12. JS base64编码和解码
  13. 《算法分析与设计(第5版)》——王晓东 - 学习记录 / 期末复习
  14. 74cms搭建 2021.03.13
  15. 《活出生命的意义》读书笔记
  16. 我的理解之JAVA中的4种访问权限
  17. Android 视频边下边播,MP4头信息在后调整头信息
  18. 解决Windows 10 家庭中文版没有组策略编辑器的问题
  19. 安装vs2015后C#注释变为英文
  20. wampserver橙色解决方法汇总

热门文章

  1. 2783: 魔法药水【二分】
  2. 计算机无法访问iTunes,iPhone连接电脑后iTunes无响应怎么办【解决方法】
  3. Oracle实现金额小写转大写函数
  4. [gazebo_gui-2] process has died [pid 4588, exit code 134, cmd /opt/ros/kinetic/lib/gazebo_ros/gzc
  5. linux中无线管理员密码,无线网管理员密码
  6. 黑苹果通过手机usb共享网络上网
  7. 黑苹果big sur版本安装安卓USB共享网络(100%成功)
  8. 如何用Go实现一款类似滴滴优步的网络约车软件(含源码)
  9. 去黑头的方法....
  10. 18天精读掌握《费曼物理学讲义卷一》 第4天 2019.6.17