使用 Byte Buddy Android :参考官方链接,以前从未使用过。 有这方面的教程吗?
代码使用 AndroidClassLoadingStrategy.Wrapping,它会在可写位置(通常在应用程序的私有目录(如 /data/data/
我们如何使用最新的android版本的字节好友android?
private fun runBuddyTest(context: Context) {
val strategy = AndroidClassLoadingStrategy.Wrapping(applicationContext.getDir("generated", Context.MODE_PRIVATE))
// Create a dynamic type (subclass of Object) and modify the "toString" method
val dynamicType = ByteBuddy()
.subclass(Any::class.java)
.method(ElementMatchers.named("toString"))
.intercept(FixedValue.value("Hello World!"))
.make()
.load(this.javaClass.classLoader, strategy)
.loaded
// Instantiate the dynamically created class and assert the "toString" method
val instance = dynamicType.getDeclaredConstructor().newInstance()
assert(instance.toString() == "Hello World!")
}
出现此错误
FATAL EXCEPTION: main
Process: com.rnadigital.bytebuddyapplication, PID: 12815
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.rnadigital.bytebuddyapplication/com.rnadigital.bytebuddyapplication.MainActivity}: java.lang.SecurityException: Writable dex file '/data/user/0/com.rnadigital.bytebuddyapplication/app_generated/d7rUqolH.jar' is not allowed.
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3782)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3922)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:139)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:96)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2443)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:205)
at android.os.Looper.loop(Looper.java:294)
at android.app.ActivityThread.main(ActivityThread.java:8177)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
Caused by: java.lang.SecurityException: Writable dex file '/data/user/0/com.rnadigital.bytebuddyapplication/app_generated/d7rUqolH.jar' is not allowed.
at dalvik.system.DexFile.openDexFileNative(Native Method)
at dalvik.system.DexFile.openDexFile(DexFile.java:406)
at dalvik.system.DexFile.<init>(DexFile.java:128)
at dalvik.system.DexFile.<init>(DexFile.java:101)
at dalvik.system.DexPathList.loadDexFile(DexPathList.java:438)
at dalvik.system.DexPathList.makeDexElements(DexPathList.java:397)
at dalvik.system.DexPathList.<init>(DexPathList.java:166)
at dalvik.system.BaseDexClassLoader.<init>(BaseDexClassLoader.java:160)
at dalvik.system.BaseDexClassLoader.<init>(BaseDexClassLoader.java:105)
at dalvik.system.DexClassLoader.<init>(DexClassLoader.java:55)
at net.bytebuddy.android.AndroidClassLoadingStrategy$Wrapping.doLoad(AndroidClassLoadingStrategy.java:580)
at net.bytebuddy.android.AndroidClassLoadingStrategy.load(AndroidClassLoadingStrategy.java:148)
at net.bytebuddy.dynamic.TypeResolutionStrategy$Passive.initialize(TypeResolutionStrategy.java:101)
at net.bytebuddy.dynamic.DynamicType$Default$Unloaded.load(DynamicType.java:6317)
at com.rnadigital.bytebuddyapplication.MainActivity.generateDynamicClassInMemory(MainActivity.kt:79)
at com.rnadigital.bytebuddyapplication.MainActivity.onCreate(MainActivity.kt:52)
at android.app.Activity.performCreate(Activity.java:8595)
at android.app.Activity.performCreate(Activity.java:8573)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1456)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3764)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3922)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:139)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:96)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2443)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:205)
at android.os.Looper.loop(Looper.java:294)
at android.app.ActivityThread.main(ActivityThread.java:8177)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
这是gradle文件
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.jetbrains.kotlin.android)
}
android {
namespace = "com.rnadigital.bytebuddyapplication"
compileSdk = 34
defaultConfig {
applicationId = "com.rnadigital.bytebuddyapplication"
minSdk = 24
targetSdk = 34
versionCode = 1
versionName = "1.0"
multiDexEnabled = true
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
}
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.1"
}
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}
}
dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose)
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.ui)
implementation(libs.androidx.ui.graphics)
implementation(libs.androidx.ui.tooling.preview)
implementation(libs.androidx.material3)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.ui.test.junit4)
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)
// implementation (libs.byte.buddy)
implementation (libs.byte.buddy.android)
}
Byte Buddy 通常将文件权限设置为
OWNER_READ
。看一下完成此操作的 FileProcessor
类。处理器未激活吗?可能您正在运行旧版本的 Byte Buddy,而没有考虑到这一点。 Android 经常变化,因此只有较新的版本才会支持更现代的 Android。