Android开发只在测试阶段添加测试库并在正式版本自动去掉测试库的方法
在实际的开发中,通常有这样一个需求,就是测试阶段需要添加一些测试库,正式版本阶段就去掉。下面拿leakcanary这个库来说明一下具体的实现方法:
1. 在app下的build.gradle添加 debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.1 //重点是debugCompile,表示测试版本编译进去,正式版本不编译进去
2. 在自定义的Application里面添加如下代码:
if (BuildConfig.DEBUG) {
Class<?> leakCanary = ReflectUtils.getReflectClass("com.squareup.leakcanary.LeakCanary");
Object isInAnalyzerProcess = ReflectUtils.invokeMethod(leakCanary, "isInAnalyzerProcess", new Class[]{Context.class}, this);
if (!(isInAnalyzerProcess instanceof Boolean && (Boolean) isInAnalyzerProcess)) {
ReflectUtils.invokeMethod(leakCanary, "install", new Class[]{Application.class}, this);
}
//if (!com.squareup.leakcanary.LeakCanary.isInAnalyzerProcess(this)) {
// com.squareup.leakcanary.LeakCanary.install(this);
//}
}
//只有在debug版本阶段才会反射调用,因为只有在debug阶段才会把leakcanary这个库编译进来。
ReflectUtils全部代码如下:
public class ReflectUtils {
public static Object invokeMethod(String clazzName, String methodName, Class<?>[] argsTypes, Object... argsValue) {
return invokeMethod(getReflectClass(clazzName), methodName, argsTypes, argsValue);
}
public static Object invokeMethod(Class clazz, String methodName, Class<?>[] argsTypes, Object... argsValue) {
if (clazz == null) {
LogUtils.d("clazz == null in invokeMethod,clazz:" + clazz + ",methodName:" + methodName);
return null;
}
final Method method = getReflectMethod(clazz, methodName, argsTypes);
if (method == null) {
LogUtils.d("method == null in invokeMethod,clazz:" + clazz + ",methodName:" + methodName);
return null;
}
try {
return method.invoke(Modifier.isStatic(method.getModifiers()) ? null : clazz, argsValue);
} catch (IllegalAccessException e) {
e.printStackTrace();
LogUtils.d("method.invoke IllegalAccessException in invokeMethod,clazz:" + clazz + ",methodName:" + methodName);
} catch (InvocationTargetException e) {
e.printStackTrace();
LogUtils.d("method.invoke InvocationTargetException in invokeMethod,clazz:" + clazz + ",methodName:" + methodName);
}
return null;
}
public static Class<?> getReflectClass(String clazzName) {
try {
return Class.forName(clazzName);
} catch (ClassNotFoundException e) {
e.printStackTrace();
LogUtils.d("Class.forName ClassNotFoundException in getReflectClass,clazzName:" + clazzName);
}
return null;
}
public static Method getReflectMethod(Class clazz, String methodName, Class<?>[] argsTypes) {
try {
//Method method = clazz.getMethod(methodName, argsTypes); //这行代码只能获取到public方法
Method method = clazz.getDeclaredMethod(methodName, argsTypes);
if (method != null && !Modifier.isPublic(method.getModifiers())) {//非public方法
method.setAccessible(true);
}
return method;
} catch (NoSuchMethodException e) {
e.printStackTrace();
LogUtils.d("clazz.getMethod NoSuchMethodException in getReflectMethod,clazz:" + clazz + ",methodName:" + methodName);
}
return null;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库