60

我知道我debugCompile只能dependency使用debug build. 是否也有一种好的、简化的方法来完成code initialization所需的工作?如果没有依赖项,其他变体将无法编译。

4

4 回答 4

97

检查@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
   }
}
于 2015-07-17T20:12:27.183 回答
60

你有几个选择。

选项 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的文件夹旁边创建一个名为的新文件夹,并为您要为调试构建添加的所有内容镜像文件夹的结构。mainmain

在这种情况下,您希望源集中的Applicationmain根本不引用 Stetho。

然后你想Application在你的debug源集中有一个类像你通常那样初始化 Stetho。

您可以在Stetho 示例中看到此设置的示例。具体来说,这里是主应用程序类这里是调试应用程序类。另请注意,他们在选择要使用的应用程序类的每个源集中设置清单。

于 2015-05-11T16:15:22.400 回答
8

使用 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'
于 2017-06-30T14:57:41.713 回答
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);
    }
于 2020-04-24T15:35:19.663 回答