java - ByteBuddy Android - Create and call a method with a certain name that directly calls another method -
this follow (though different) question thread: java - create anonymous exception subclass name
i'm trying send non-crash error reports crashlytics on android , rafael winterhalter achieved displayed in different rows in crashlytics ui. requirement send different exception subclasses every issuetype.
it looks in screenshot below now.
next issue still doesn't show on 1 glance actual exception-type is. instead shows function-name error sent from. having learnt magic of byte buddy, thought - maybe it's possible create static function in custom exception subclass, directly calls
crashlytics.logexception
function. i've seen it's possible use interceptor class (and call code there), guess crashlytics show function name inside interceptor.
is possible create static method name issuetype
, have directly call crashlytics.logexception
?
here's updated code far:
public static void craslyticsrecorderror(string issuetype, string errormsg) { // byte buddy needs 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 exception 'issuetype' class name , create method // has name, crashlytics show 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(); } }
crash stacktrace:
java.lang.illegalstateexception: public static void com.crashlytics.android.crashlytics.logexception(java.lang.throwable) not take 0 arguments @ net.bytebuddy.implementation.methodcall$appender.apply(methodcall.java:1998) @ net.bytebuddy.dynamic.scaffold.typewriter$methodpool$record$fordefinedmethod$withbody.applycode(typewriter.java:620) @ net.bytebuddy.dynamic.scaffold.typewriter$methodpool$record$fordefinedmethod$withbody.applybody(typewriter.java:609) @ net.bytebuddy.dynamic.scaffold.typewriter$methodpool$record$fordefinedmethod.apply(typewriter.java:526) @ net.bytebuddy.dynamic.scaffold.typewriter$default$forcreation.create(typewriter.java:4159) @ net.bytebuddy.dynamic.scaffold.typewriter$default.make(typewriter.java:1633) @ net.bytebuddy.dynamic.scaffold.subclass.subclassdynamictypebuilder.make(subclassdynamictypebuilder.java:174) @ net.bytebuddy.dynamic.scaffold.subclass.subclassdynamictypebuilder.make(subclassdynamictypebuilder.java:155) @ net.bytebuddy.dynamic.dynamictype$builder$abstractbase.make(dynamictype.java:2559) @ net.bytebuddy.dynamic.dynamictype$builder$abstractbase$delegator.make(dynamictype.java:2661) @ org.utils.fabric.craslyticsrecorderror(fabric.java:69) @ android.os.messagequeue.nativepollonce(native method) @ android.os.messagequeue.next(messagequeue.java:323) @ android.os.looper.loop(looper.java:143) @ android.app.activitythread.main(activitythread.java:7224) @ java.lang.reflect.method.invoke(native method) @ com.android.internal.os.zygoteinit$methodandargscaller.run(zygoteinit.java:1230) @ com.android.internal.os.zygoteinit.main(zygoteinit.java:1120)
yes, of course possible , documentation contains example. can define method follows:
new bytebuddy() .subclass(exception.class) .definemethod("issuetype", void.class, ownership.static, visibility.public) .withparameters(exception.class) .intercept(methodcall.invoke(crashalytics.getmethod("logexception")) .withargument(0));
this define method
public static void issuetype(exception e) { crashalytics.logexception(e); }
within generated class.
Comments
Post a Comment