我知道我debugCompile
只能dependency
使用debug build
. 是否也有一种好的、简化的方法来完成code initialization
所需的工作?如果没有依赖项,其他变体将无法编译。
4 回答
检查@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:在所有构建中包含 Stetho(使用compile
代替debugCompile
),并且仅在您的类中初始化它以Application
进行调试构建。
这很容易做到。在你的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用于所有构建中所需的代码
您的应用程序代码目前可能都在main
源集中。您可以简单地在应用程序中debug
的文件夹旁边创建一个名为的新文件夹,并为您要为调试构建添加的所有内容镜像文件夹的结构。main
main
在这种情况下,您希望源集中的Application
类main
根本不引用 Stetho。
然后你想Application
在你的debug
源集中有一个类像你通常那样初始化 Stetho。
您可以在Stetho 示例中看到此设置的示例。具体来说,这里是主应用程序类,这里是调试应用程序类。另请注意,他们在选择要使用的应用程序类的每个源集中设置清单。
使用 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'
还有更多的主要方法可以连接 stetho 或任何其他 lib 仅用于调试构建 - 使用反射:1)通过 debugImplementation 连接您的 lib - debugImplementation 'com.facebook.stetho:stetho:1.5.1'
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);
}