android debug bridge tools_如何优雅的管理多环境下的Android代码
秦子帅明确目标,每天进步一点点.....
作者 | 小码哥哥地址 | juejin.im/post/5e1ef261f265da3e0535f10a
介绍日常开发过程中除了主工程代码,肯定也少不了调试代码,如日志、调试开关、调试工具、功能Mock等等,此时就需要一个开发阶段使用的开发环境。现在很多项目都使用云测试,三方云测试平台(如testin, 阿里云等等)测试时往往无法跳过登录,所以要在云测的安装包中内置登录token,还要指定云测接口等等一些云测场景下的一些特殊功能,此时就需要一个专为三方云测平台使用的云测环境。项目上线当然需要有线上环境 此外AS/Gradle还内置了debug环境和release环境。那么多不同的环境,代码如何去做管理? 又如何把不同环境的代码完全隔离开来?我们必须要保证调试、Mock等等这些业务无关的代码完全不能影响到线上。首先, 我们使用AS新建一个项目, 我们看看AS/Gradle有什么?如上图所示, AS已经在src目录下创建三个SourceSet目录,分别是androidTest, main和test,其中main是主工程目录,其他两个是用于单元测试目录。AS/Gradle只有这三个SourceSet目录吗?当然不是!我们知道build.gradle配置文件中,可以配置buildTypes.默认已经有debug和release两个buildType. 我们还可以自定义一个buildType名字叫custom.
android { ... buildTypes { debug { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } custom { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } }}
执行同步操作后,我们点开AS左侧的"build Variants",我们可以选择具体使用哪个buildType很多人可能会问, 这有什么用?这真的很有用!上面说过AS已经在src目录下创建了名为"main"的SourceSet目录和另外两个test目录。此时我们可以在src目录下再创建一个debug/release/custom目录,目录下的内容和main目录下内容一致。main目录一直处于激活状态,但同一时刻只会有一个buildType的SourceSet目录会被激活,如下图所示。编译时,Gradle会自动合并多个SourceSet目录。AS/Gradle还支持根据buildType引入其他module或者三方仓库
dependencies { ... debugImplementation project(":debugLib1") debugApi 'com.android.support:appcompat-v7:28.0.0' customImplementation project(":customLib") customApi 'com.google.code.gson:gson:2.8.5' ... }
除了buildType,AS/Gradle还支持productFlavors,内容和buildTypes类似,可自行百度这里不再赘述。需要强调的是Gradle在编译时可以同时有一个buildType,一个productFlavor和main三个SourceSet共存,编译过程中会自动合并三个SourceSet目录.现在,如何使用多环境已经显而易见了,我们只要按需自定义buildType/productFlavor,然后将调试或者Mock的代码放到对应的buildType/productFlavor的SourceSet下就可以做到不同环境代码分离了。代码分离就一切顺利了吗?实际操作过程中会发现,buildType/productFlavor是可以直接引用到main下面的代码,相反却是不可以的,因为一旦做buildType/productFlavor切换操作的时候,main就可能找不到buildType/productFlavor中的类了。问题来了,既然main无法直接引用buildType/productFlavor中的代码,那么buildType/productFlavor中的代码如何初始化?main又如何调用这些类呢?就以上面说的云测环境做例子,假设我为云测创建了一个productFlavor名字叫cloud,我想要在云测环境app执行初始化的时候调用一次登录接口,这样就可以内置token而不需要在云测环境手动登录了,
public class LoginManager { public static void login() { //do login }}
如何触发这个登录操作是一个问题。通常我们会在自定义Application的onCreate()方法中执行初始化。
public class App extends Application { @Override public void onCreate() { LoginManager.login(); //这里不应该直接引用LoginManager, 因为LoginManager在productFlavor为cloud的SourceSet中, 一旦切到其他productFlavor,LoginManager类就找不到了 }}
这里有一个办法 在cloud中新建一个CloudApp继承自main中的App,然后在could的AndroidManifest中引用
android:name="chao.app.cloud.CloudApp" tools:replace="android:name" //必要, 使用CloudApp替换App ... />
public class CloudApp extends App { @Override public void onCreate() { super.onCreate(); LoginManager.login(); //这样就不用担心buildType/productFlavor切换导致类找不到的问题了 }}
简单的场景里这个方法是很有效的,场景再复杂一点呢如果BuildVariants选择cloudDebug,即productFlavor是cloud,buildType是debug,debug也需要有自己的初始化,但是AndroidManifest中Application最终只能有一个。所以稍微复杂点的场景问题会变得很棘手。另外由于存在多环境切换,buildType/productFlavor中的类是不能直接被调用的。
如何解决ServicePool是一个用于组件化通信的神器。可以很有效的解决上述问题。https://juejin.im/post/5e1e76c6518825267f699a3d使用ServicePool初始化Service初始化代替Application初始化,cloud中定义一个CloudInit,debug中定义一个DebugInit.
public class App extends Application { @Override public void onCreate() { super.onCreate(); AndroidServicePool.init(this); //初始化ServicePool }}
@Init(lazy = false) //ServicePool默认所有组件使用懒加载,这里取消掉懒加载模式,让ServicePool初始化后理解加载这个Service@Servicepublic class CloudInit implements IInitService { @Override public void onInit() { LoginManager.login(); }}
@Init(lazy = false) //ServicePool默认所有组件使用懒加载,这里取消掉懒加载模式,让ServicePool初始化后理解加载这个Service@Servicepublic class DebugInit implements IInitService { @Override public void onInit() { //do something }}
上面已解决了多环境初始化问题,那么如何解决buildType/productFlavor下类又是如何被调用的呢?相信看完ServicePool你一定能找到答案。本文档涉及demo代码:https://github.com/luqinx/Documents
---END---
创作不易,点个“在看”
android debug bridge tools_如何优雅的管理多环境下的Android代码相关推荐
- android debug bridge tools_飞凌干货丨Android 应用程序如何获取system权限
当Android应用程序用到重启系统.关闭系统.修改系统时间等功能时,需要用到system权限. 本文以OKxx18平台实现重启功能的应用程序PermissionTest为例,说明获取系统权限的方法. ...
- Android开发工具——ADB(Android Debug Bridge) 一概览
Android Debug Bridge (adb) 是一个android开发人员必会的多功能的调试工具,确实它的名字一样,它在开发者和目标机器之间,架起了一座bridge. adb的用法很简单,只要 ...
- [ADB]ADB(Android Debug Bridge)简介及基础(不包含命令)
"Android Debug Bridge (adb) is a versatile command line tool that lets you communicate with an ...
- adb(Android debug bridge)命令
From:https://www.cnblogs.com/huanyou/p/5133737.html ADB 用法大全: github 地址:https://github.com/mzlogin/a ...
- Android Debug Bridge(ADB)学习总结
Android Debug Bridge Android调试桥(ADB)是一种多用途的命令行工具.通过它我们可以和模拟器或者设备通信.ADB是一个客户端-服务器程序,包括三个组成部分: 客户端(Cli ...
- ABD — android debug bridge 简略介绍
ABD - android debug bridge 简略介绍 文章目录 ABD - android debug bridge 简略介绍 一.adb是什么? 二.组成部分 三.adb 常用命令 四.总 ...
- Android Debug Bridge(adb)
Adb google官方文档翻译,源文档地址如下 https://developer.android.google.cn/studio/command-line/adb Android Debug B ...
- Android开发者指南(1) —— Android Debug Bridge(adb)
Android Debug Bridge Android调试桥接器,简称adb,是用于管理模拟器或真机状态的万能工具,采用了客户端-服务器模型,包括三个部分: * 客户端部分,运行在开发用的电脑上,可 ...
- Android Debug Bridge 技术实现原理
Android Debug Bridge 技术实现原理 ADB(Android Debug Bridge)技术实现 =============== I.总览 =============== ADB用来 ...
最新文章
- 区块链技术之Fabric逻辑架构详解
- 创建一个纯色的背景图
- 23 | MySQL是怎么保证数据不丢的?
- Centos7换yum源
- springsecurity 认证之密码模式
- 谁将成为下一个风口?
- python怎么定义全局变量_python中如何定义全局变量
- 精妙的SQL和SQL SERVER 与ACCESS、EXCEL的数据导入导出转换
- 几款ReactJS最优秀的UI框架
- S.O. 推出程序员身价计算器,看看自己值多少钱?
- 实验一高频小信号调谐放大器
- 获得代理ippython_Python3.x:免费代理ip的批量获取并入库
- Boost Asio介绍
- Neural Collaborative Filtering
- ShareTechnote系列LTE(10):多小区多RAT之间的交互
- 6.Striped64源码解析
- 解决mac登录APPLE ID无限重复弹窗提示登录
- 结构化数据和非结构化数据的提取【Python篇】
- 神奇的sqrt函数以及高精度记时函数
- 阿里云王牌架构师二问开发者:容器和虚拟化你会怎么选?