Byte Buddy の Hello World の Android 非依存版の UnitTest と Android 版です。
Byte Buddy 本家リンク
UnitTest版 helloWorld()
build.gradle
implementation 'net.bytebuddy:byte-buddy:1.10.1'
本家サンプルのhelloWorld()と同等なコード(UnitTest版)
// @See https://github.com/raphw/byte-buddy#hello-world
@Test
fun helloWorld() {
// Object 型のサブクラスを作成し、toString() を "Hello World!" と表示されるように
// intercept する。
val dynamicType = ByteBuddy()
.subclass(Any::class.java)
.method(ElementMatchers.named("toString"))
.intercept(FixedValue.value("Hello World!"))
.make()
.load(javaClass.classLoader)
.loaded
// 作成した型のインスタンスを生成して toString() の内容をテストする。
assertEquals("Hello World!", dynamicType.newInstance().toString())
}
Android版 helloWorld()
build.gradle
implementation 'net.bytebuddy:byte-buddy:1.10.1'
implementation 'net.bytebuddy:byte-buddy-android:1.10.1'
※Android 版は UnitTest版 と load() の部分が異なるので注意。
実行時に java.lang.ClassNotFoundException: Didn't find class "java.lang.instrument.ClassFileTransformer"
とか言って怒られます。
本家サンプルのhelloWorld()と同等なコード(Android版)
fun helloWorld() {
// Object 型のサブクラスを作成し、toString() を "Hello World!" と表示されるように
// intercept する。
val dynamicType = ByteBuddy()
.subclass(Any::class.java)
.method(ElementMatchers.named("toString"))
.intercept(FixedValue.value("Hello World!"))
.make()
// Memo: The following Exception occurs when you call ".load(javaClass.classLoader)" on Android
// java.lang.ClassNotFoundException: Didn't find class "java.lang.instrument.ClassFileTransformer"
.load(
this::class.java.classLoader,
AndroidClassLoadingStrategy.Wrapping( application.getDir( "dexgen", Context.MODE_PRIVATE ) )
)
.loaded
// 作成した型のインスタンスを生成して toString() の内容を Toast で表示する。
Toast.makeText(this, dynamicType.newInstance().toString(), Toast.LENGTH_SHORT).show()
}