我知道我可以使用debugCompile
仅为dependency
提取debug build
。是否有一种良好的,简化的方法来执行所需的code initialization
?如果没有依赖关系,其他变体将无法编译。
答案 0 :(得分:86)
检查@Tanis答案。
你也可以使用这样的东西:
仅在调试版上添加库。
dependencies {
debugCompile 'com.facebook.stetho:stetho:1.1.1
}
在您的应用程序中,您可以:
public class ExampleApplication extends Application {
@Override public void onCreate() {
super.onCreate();
StethoUtils.install(this);
}
}
然后,您可以在调试/发布版本中创建不同的StethoUtils
类。
在src/debug/java/
public class StethoUtils{
public static void install(Application application){
Stetho.initialize(
Stetho.newInitializerBuilder(application)
.enableDumpapp(Stetho.defaultDumperPluginsProvider(application))
.enableWebKitInspector(Stetho.defaultInspectorModulesProvider(application))
.build());
}
}
在src/release/java/
public class StethoUtils{
public static void install(Application application){
// do nothing
}
}
答案 1 :(得分:53)
您有几个选择。
选项1:包含所有版本的Stetho(使用compile
而非debugCompile
)并仅在Application
类中初始化它以进行调试版本。< / p>
这很容易做到。在Application
课程中,请检查BuildConfig.DEBUG
,如下所示:
if (BuildConfig.DEBUG) {
Stetho.initialize(
Stetho.newInitializerBuilder(this)
.enableDumpapp(Stetho.defaultDumperPluginsProvider(this))
.enableWebKitInspector(Stetho.defaultInspectorModulesProvider(this))
.build()
);
}
选项2:仅包含用于调试版本的Stetho,并为调试和发布版本创建不同的Application
类。
感谢Gradle,应用程序可以为不同的构建变体提供不同的源集。默认情况下,您具有发布和调试版本类型,因此您可以拥有三个不同的源集:
您的应用程序代码可能目前都在main
源集中。您只需在应用程序的debug
文件夹旁边创建一个名为main
的新文件夹,并镜像main
文件夹的结构,以便为调试版本添加所有内容。
在这种情况下,您希望Application
源集中的main
课程根本不会引用Stetho。
然后,您希望Application
源集中的debug
类像往常一样初始化Stetho。
您可以在Stetho sample中查看此设置的示例。具体而言,here's the main Application class和here's the debug Application class。另请注意,他们在每个源集中设置了清单,用于选择要使用的Application类。
答案 2 :(得分:3)
使用java反射可能是一个完美的想法:
private void initStetho() {
if (BuildConfig.DEBUG) {
try {
Class<?> stethoClazz = Class.forName("com.facebook.stetho.Stetho");
Method method = stethoClazz.getMethod("initializeWithDefaults",Context.class);
method.invoke(null, this);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
然后我们可以调试编译stetho:
debugCompile 'com.facebook.stetho:stetho:1.5.0'
答案 3 :(得分:0)
还有更多的基本方法可以将stetho或任何其他lib连接到调试版本-使用反射:
1)通过debugImplementation-debugImplementation 'com.facebook.stetho:stetho:1.5.1'
连接您的lib
2)仅使用静态成员实现类-DynamicClassUtils:
public class DynamicClassUtils {
private static final String TAG = "DynamicClassUtils";
public static void safeInvokeStaticMethod(String fullClassName, String methodName, Class<?>[] types, Object... args) {
try {
Class<?> aClass = Class.forName(fullClassName);
Method aMethod = aClass.getMethod(methodName, types);
aMethod.invoke(null, args);
} catch (Throwable e) {
if (BuildConfig.DEBUG) {
Log.e(TAG, "Error when invoking static method, message: " + e.getMessage() + ", class: " + e.getClass());
e.printStackTrace();
}
}
}
public static <T> T safeGetInstance(String fullClassName, Object... args) {
try {
ArrayList<Class<?>> formalParameters = new ArrayList<>();
for (Object arg : args) {
formalParameters.add(arg.getClass());
}
Class<?> aClass = Class.forName(fullClassName);
Constructor<?> ctor = aClass.getConstructor(formalParameters.toArray(new Class<?>[0]));
return (T) ctor.newInstance(args);
} catch (Throwable e) {
if (BuildConfig.DEBUG) {
Log.e(TAG, "Error when creating instance, message: " + e.getMessage());
e.printStackTrace();
}
return null;
}
}
3)使用该类初始化Stetho及其网络拦截器:
if (BuildConfig.DEBUG) {
Class<?>[] argTypes = new Class<?>[1];
argTypes[0] = Context.class;
DynamicClassUtils.safeInvokeStaticMethod("com.facebook.stetho.Stetho", "initializeWithDefaults", argTypes, this);
}
if (BuildConfig.DEBUG) {
Interceptor interceptor = DynamicClassUtils.safeGetInstance("com.facebook.stetho.okhttp3.StethoInterceptor");
if (interceptor != null) client.addNetworkInterceptor(interceptor);
}