1

Androidのメソッドproxy(...)の下にbyteBuddyオブジェクトを作成し、byteBuddyオブジェクトでいくつかのメソッドを呼び出そうとしています:

<T> T proxy(Class<T> clz, InvocationHandler invocationHandler) {
    ByteBuddy byteBuddy = null;
    try {
        byteBuddy = new ByteBuddy(ClassFileVersion.JAVA_V6);
    } catch (Throwable e) {
        //e.printStackTrace();
    }
    if(byteBuddy!=null) {
        Class<?> enhanced = byteBuddy
                .subclass(clz, ConstructorStrategy.Default.IMITATE_SUPER_TYPE)
                .method(ElementMatchers.not(ElementMatchers.isDeclaredBy(Object.class)))
                .intercept(InvocationHandlerAdapter.of(invocationHandler))
                .make().load(getClass().getClassLoader(), classLoadingStrategy)
                .getLoaded();

        ...

しかし、次のとおりです。

load(getClass().getClassLoader(), classLoadingStrategy)

ByteBuddy が例外をスローします:

java:781) 06-11 21:29:23.371 12028-12028/com.example.AndroidOverlay W/System.err﹕ at java.lang.BootClassLoader.loadClass(ClassLoader.java:841) 06-11 21:29:23.371 12028-12028/com.example.AndroidOverlay W/System.err﹕ at java.lang.ClassLoader.loadClass(ClassLoader.java:504) 06-11 21:29:23.371 12028-12028/com.example.AndroidOverlay W/System .err﹕ ... 25 more 06-11 21:29:23.371 12028-12028/com.example.AndroidOverlay W/System.err﹕ 原因: java.lang.NoClassDefFoundError: ブート クラス ローダーを使用してクラスが見つかりません。利用可能なスタックがありません 371 12028-12028/com.example.AndroidOverlay W/System.err﹕ ... 25 more 06-11 21:29:23.371 12028-12028/com.example.AndroidOverlay W/System.err﹕ 原因: java.lang .NoClassDefFoundError: ブート クラス ローダーを使用してクラスが見つかりません。利用可能なスタックがありません 371 12028-12028/com.example.AndroidOverlay W/System.err﹕ ... 25 more 06-11 21:29:23.371 12028-12028/com.example.AndroidOverlay W/System.err﹕ 原因: java.lang .NoClassDefFoundError: ブート クラス ローダーを使用してクラスが見つかりません。利用可能なスタックがありません

http://central.maven.org/maven2/com/google/android/tools/dx/1.7/dx-1.7.jar および byte-buddy-0.6.8.jar, byte- の dx-1.7.jar を使用していますバディ-android-0.6.8.jar

何か不足していますか?私はまた、あなたのAndroidサンプルアプリケーションで動的タイプを実行できませんでした.(Failed resolution of: Lorg/objectweb/asmType;) も取得します.

EDIT1 : Lollipop を使用しています。これが AndroidClassLoadingStrategy のセットアップ方法です。

final File dir = this.getDir("dexgen", Context.MODE_PRIVATE);
    Messenger.setClassLoadingStrategy(new AndroidClassLoadingStrategy(dir));

メソッドproxy(...)があるクラスMessengerに設定します

public static void setClassLoadingStrategy(ClassLoadingStrategy cls) {
    classLoadingStrategy = cls;
}

そしてclassLoadingStrategyは次のように定義されています

private static ClassLoadingStrategy classLoadingStrategy;

編集 2: 結局、私は ByteBuddy のサンプル アプリケーションを使用して、Android lollipop を置き換えるための行を試しました

File file = TestActivity.this.getDir(RandomString.make(), Context.MODE_PRIVATE);

交換する必要があるこれらの1つについて、それらをすべて試してみましたが、異なるクラスアクティビティからだけで、すべて同じ例外が発生します

File file = getCodeCacheDir(); //NOT WORKING
// File file = getApplicationContext().getCodeCacheDir(); //NOT WORKING
// File file = getBaseContext().getCodeCacheDir(); //NOT WORKING
// File file = TestActivity.this.getCodeCacheDir(); //NOT WORKING

まだ例外:

06-12 23:18:57.916    1947-1947/net.bytebuddy.android.test W/net.bytebuddy﹕ java.lang.IllegalStateException: Cannot load class net.bytebuddy.renamed.java.lang.Object$ByteBuddy$uSYJ5787$auxiliary$MBywjCuh

ここでエラーを再現する可能性があるため、Web サイトのソースを作成して配置しました。

bashism.com/shared/ByteBuddyTest.tar.gz

編集3:

Android バージョン: 5.0.1 ロリポップ

デバイス: Samsung Galaxy S4

IDE: IntelliJ アイデア 14.1.3

編集4: メインアクティビティ内で変更した後:

File file = TestActivity.this.getDir(RandomString.make(), Context.MODE_PRIVATE);

および net.bytebuddy.android.AndroidClassLoadingStrategy 内

public ForSdkCompiler(DexOptions dexFileOptions, CfOptions dexCompilerOptions) {
dexFileOptions.targetApiLevel = 13;
this.dexFileOptions = dexFileOptions;
this.dexCompilerOptions = dexCompilerOptions;

}

動作/安定しているようで、すぐにさらにデバッグします

4

1 に答える 1

2

上記のコメントでほのめかしたように、問題は、生成された DEX ファイルが現在新しすぎて (新しいバージョンでは「拡張オペコード」が導入されているようです)、基礎となる ART 機構が処理できないことです。実際の問題は、さまざまなデフォルト値を持つさまざまなデバイスに起因する可能DexOptions.targetApiLevel性があります (実際の API ビルド ターゲットを無視する可能性があります)。これを修正するには、適切な dex ファイルが確実に生成されるように、classes.dexファイルを含むすべてのクラス ロード戦略で、この値を 0 またはそれ以下に設定する必要があります。13たとえば、 @raphw'sAndroidClassLoadingStrategyでは、DexProcessor.ForSdkCompilerコンストラクターを変更して、この値を具体的に設定できます。

public ForSdkCompiler(DexOptions dexFileOptions, CfOptions dexCompilerOptions) {
    dexFileOptions.targetApiLevel = 13;
    this.dexFileOptions = dexFileOptions;
    this.dexCompilerOptions = dexCompilerOptions;
}
于 2015-08-08T12:17:13.653 に答える