这是此线程的后续问题(尽管有所不同):
Java - Create anonymous Exception subclass with a certain name

我正在尝试将非崩溃错误报告发送到Android上的Crashlytics,并且感谢Rafael Winterhalter,我现在实现了它们在Crashlytics UI中显示在不同行中的功能。要求是为每个issueType发送不同的Exception子类。

现在看起来像下面的屏幕截图。

java - ByteBuddy Android-创建并调用具有特定名称的方法,该方法直接调用另一个方法-LMLPHP
下一个问题是,乍一看它仍然没有真正显示出实际的异常类型。而是仅显示发送错误的函数名称。现在,我已经了解了字节伙伴的魔力,也许可以在自定义Exception子类中创建一个静态函数,直接调用Crashlytics.logException函数。我已经看到可以使用拦截器类(然后从那里调用代码),但是我想Crashlytics总是会在此拦截器中显示函数名称。

是否可以创建名称为issueType的静态方法并直接调用Crashlytics.logException

到目前为止,这是我更新的代码:

public static void craslyticsRecordError(String issueType, String errorMsg)
{
    // byte buddy needs a private directory
    File filesDir = GameApplication.getAppContext().getFilesDir();
    String dirPath = filesDir.getAbsolutePath() + File.separator + "ByteBuddy";
    File byteBuddyPrivateDirectory = new File(dirPath);
    if (!byteBuddyPrivateDirectory.exists())
    {
        byteBuddyPrivateDirectory.mkdirs();
    }
    GameLog.d("ByteBuddyDir:" + byteBuddyPrivateDirectory);

    try
    {
        // dynamically create an exception with 'issueType' as its class name and also create method
        // that has this name, so that Crashlytics will show that name
        Class<? extends Exception> dynamicType = new ByteBuddy()
                .subclass(Exception.class)
                .name(issueType)
                .defineMethod(issueType, void.class, Ownership.STATIC, Visibility.PUBLIC)
                .withParameters(Throwable.class)
                .intercept(MethodCall.invoke(Crashlytics.class.getMethod("logException", Throwable.class)))
                .make() // line of crash
                .load(Fabric.class.getClassLoader(), new AndroidClassLoadingStrategy.Wrapping(byteBuddyPrivateDirectory))
                .getLoaded();

        Exception e = dynamicType.getConstructor(String.class).newInstance(errorMsg);

        Method method = Crashlytics.class.getMethod(issueType, Exception.class);
        method.invoke(null, e);
    }
    catch (Exception e1)
    {
        Exception e = new Exception(issueType + "-" + errorMsg);
        Crashlytics.logException(e);
        e1.printStackTrace();
    }
}


崩溃Stacktrace:

java.lang.IllegalStateException: public static void com.crashlytics.android.Crashlytics.logException(java.lang.Throwable) does not take 0 arguments
    at net.bytebuddy.implementation.MethodCall$Appender.apply(MethodCall.java:1998)
    at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod$WithBody.applyCode(TypeWriter.java:620)
    at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod$WithBody.applyBody(TypeWriter.java:609)
    at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod.apply(TypeWriter.java:526)
    at net.bytebuddy.dynamic.scaffold.TypeWriter$Default$ForCreation.create(TypeWriter.java:4159)
    at net.bytebuddy.dynamic.scaffold.TypeWriter$Default.make(TypeWriter.java:1633)
    at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:174)
    at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:155)
    at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase.make(DynamicType.java:2559)
    at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase$Delegator.make(DynamicType.java:2661)
    at org.utils.Fabric.craslyticsRecordError(Fabric.java:69)
    at android.os.MessageQueue.nativePollOnce(Native Method)
    at android.os.MessageQueue.next(MessageQueue.java:323)
    at android.os.Looper.loop(Looper.java:143)
    at android.app.ActivityThread.main(ActivityThread.java:7224)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

最佳答案

是的,这当然是可能的,并且文档甚至包含示例。您可以如下定义方法:

new ByteBuddy()
  .subclass(Exception.class)
  .defineMethod("issueType", void.class, Ownership.STATIC, Visibility.PUBLIC)
  .withParameters(Exception.class)
  .intercept(MethodCall.invoke(Crashalytics.getMethod("logException"))
                       .withArgument(0));


这将定义一个方法

public static void issueType(Exception e) {
  Crashalytics.logException(e);
}


在您生成的类中。

10-05 21:14
查看更多