Android模块化分层化之: maven 库中上传的 aar 包 获取 BuildConfig 相关常量值
来源:互联网 发布:津天元渔具淘宝网 编辑:程序博客网 时间:2024/05/21 22:24
最近在做项目分层化的一些工作,具体思路是将原有项目一些基础服务模块和设备服务模块抽离出来,上传到本地的 Maven 服务器,然后再通过在主项目中的 build.gradle 文件中通过
compile
语句进行导包处理。但通过这种方法编译成的 aar 包只能是 release 版本,无法使用到BuildConfig
动态设置的一些常量,比如常见的「Debug 日志开关」,我们一般都是在日志类通过BuildConfig.DEBUG
来获取包状态,从而设置是否要打印出日志。
题外话
这里特别提一下为什么要用 Maven 这种方式,实际上单纯的抽离模块可以通过子模组的方式,Git 也有 submodule 这样的子模组管理方法,但用 Git 管理子模组会有很多问题,比如项目引用子模组的指针问题,在一个并行开发团队中,子模组指针往往会导致很多出人意料的问题,以后我会专门的在这方面写一篇博客做一个解析。
通过把子模块上传至 Maven 库有很多好处,比如导入起来很方便,只需要在配置文件中 compile 即可,而且开发该模块的时候只需要单独打开该子模组的代码,不像通过 Git 管理的依赖子模组,即使你只是为了修改子模组代码,也需要打开原来的完整项目,然后在项目下的子 module 进行开发,最后子模组代码和主项目代码得同时提交。
compile 'com.github.bumptech.glide:okhttp-integration:1.4.0'
另外它还有一些安全性的好处。通过这种方式,实际上也是一种对代码的保护,客户端开发人员不会轻易的修改这部分代码。
具体如何通过 Android studio 构建 maven 库,请移步 Gradle实战:发布aar包到maven仓库
具体问题
我把项目中的一些基础服务专门抽离了出来,其中就包括了一些跟 Log 日志打印相关的代码,原来项目中在build.gradle 中的 buildTypes 中设置了 DEVELOP_MODE
常量,来控制在不同渠道打包下的 Log 开关。
buildTypes { debug { // log日志开关 buildConfigField("boolean", "DEVELOP_MODE", "true") } release{ buildConfigField("boolean", "DEVELOP_MODE", "false") }
然后,在具体的日志类中调用,动态获取 DEVELOP_MODE
值
public class DEBUG { public final static boolean DEVELOP_MODE = BuildConfig.DEVELOP_MODE;}
现在,当我把这部分代码单独抽离出来到名叫「middleWare」的子 library 后,即使我仍然可以在该 library 中的 build.gradle 文件设置上述的 buildTypes 代码,但通过 maven 编译出来的 aar 包只能是 release 版本,自然也无法获取到那些动态配置的常量值。
所以,只能通过获取引入项目的 BuildConfig 类来获取了,所以我们自然的想到了用反射。下面是具体代码,注释也比较详细:
public class BuildConfigProvider { private static Context sContext; private static String packageName; /** * 通过反射获取ApplicationContext * * @return */ private static Context getContext() { if (sContext == null) { try { final Class<?> activityThreadClass = Class.forName("android.app.ActivityThread"); final Method currentActivityThread = activityThreadClass.getDeclaredMethod("currentActivityThread"); final Object activityThread = currentActivityThread.invoke(null); final Method getApplication = activityThreadClass.getDeclaredMethod("getApplication"); final Application application = (Application) getApplication.invoke(activityThread); sContext = application.getApplicationContext(); } catch (Exception e) { e.printStackTrace(); } } return sContext; } /** * 通过反射获取包名 * * @return */ private static String getPackageName() { if (packageName == null) { try { final Class<?> activityThreadClass = Class.forName("android.app.ActivityThread"); final Method currentPackageName = activityThreadClass.getDeclaredMethod("currentPackageName"); packageName = (String) currentPackageName.invoke(null); } catch (Exception e) { packageName = getContext().getPackageName(); } } return packageName; } /** * 获取具体的域值 * * @return */ public static Object getBuildConfigValue(String fieldName) { try { Class<?> clazz = Class.forName(getPackageName() + ".BuildConfig"); Field field = clazz.getField(fieldName); return field.get(null); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IndexOutOfBoundsException e) { e.printStackTrace(); } return ""; }}
这里实际上可以用一个方法获取 context 然后就直接可以拿到 packageName,为了看的清晰,所以分成两个方法了。
然后把之前那个 DEBUG 类适当改动下,将 DEBUG 类放在该子模块代码中:
public final static boolean DEVELOP_MODE = isDevelopMode(); static boolean isDevelopMode(){ return (boolean)BuildConfigProvider.getBuildConfigValue("DEVELOP_MODE"); }}
这样只需要在引入项目中的 buildTypes 中设置 DEVELOP_MODE
的各种配置就能在项目中动态的调用日志开关了。
比如我们项目中的日志打印类 Glog.class
,每个日志等级的打印前都会有 DEBUG.DEVELOP_MODE 的判断:
public class GLog { public static void d(String message) { if(TextUtils.isEmpty(message)){ return; } //判断日志开关 if (DEBUG.DEVELOP_MODE) { final StackTraceElement[] stack = new Throwable().getStackTrace(); final int i = 1; final StackTraceElement ste = stack[i]; Log.println(Log.DEBUG, LOG_TAG, String.format("[%s][%s][%s]%s", ste.getFileName(), ste.getMethodName(), ste.getLineNumber(), message)); } }}
这里只是通过打印日志的例子来展示如何在 aar 中调用主项目的 BuildConfig 类获取编译类型,其他各种 BuildConfig 中的域都可以用这种方式获取到
- Android模块化分层化之: maven 库中上传的 aar 包 获取 BuildConfig 相关常量值
- Android中颜色常量值
- maven pom文件中定义常量值
- Android模块化编程之引用本地的aar
- Android 模块化编程之引用本地的 aar
- Android模块化编程之引用本地的aar
- Android模块化编程之引用本地的aar
- Android模块化编程之引用本地的aar
- Android模块化编程之引用本地的aar
- Android开发 模块化编程之引用本地的aar
- Android模块化编程之引用本地的aar
- Android模块化编程之引用本地的aar
- Android模块化编程之引用本地的aar
- 与路由相关的常用度量值
- Android Studio模块化编程实践之aar
- Android模块化开发中统计aar库的代码覆盖率
- [整理]JavaScript闭包对象中定义常量和用取值器来获取常量值
- android 上传aar到私有maven服务器
- <<Linux内核设计与实现>>读书笔际(五)-系统调用
- static的作用
- C#--02--mysql数据库
- java Print流 和 重定向
- Java 多线程下的单例模式
- Android模块化分层化之: maven 库中上传的 aar 包 获取 BuildConfig 相关常量值
- listview去掉分割线
- Adapter中用不了getWindowManager()方法怎么办?
- 基于 10 大编程语言的 30 个深度学习库
- C# 使用Http Post + SharpPcap监听方式处理C/S通讯
- Redis3.0.7 cluster/集群 安装配置教程
- Android DrawerLayout 点击事件穿透
- JDBC使用详解 (oracle、mysql、postgresql)
- Scrapy 爬虫框架入门案例详解