3

モジュール A とモジュール B の 2 つのモジュールを含む Android Studio android プロジェクトがあります。これらのモジュールをビルドしてテストし、.aar ファイルとして配布しています。.aars を使用する親アプリを実行すると、AbstractMethodError が発生し、その理由がわかりません。クラスとインターフェースの -keep フラグを両方のモジュールの dexguard-project.txt ファイルに含めましたが、それが機能することを期待していましたが、役に立ちませんでした。プロジェクトの詳細は次のとおりです。

モジュール A には、Util.class というクラスが含まれています。

public class Util {

private static CustomObject getObjectFromDb(Context context) {
    return new CustomObject();
}

public static class GetObjectTask extends AsyncTask<Context, Void, CustomObject> {
    FetchCustomObjectListener mListener;
    Context mContext;

    public GetObjectTask(Context context, FetchCustomObjectListener listener) {
        mListener = listener;
        mContext = context;
    }

    @Override
    protected CustomObject doInBackground(Context... params) {
        return getObjectFromDb(mContext);
    }

    @Override
    protected void onPostExecute(CustomObject d) {
        super.onPostExecute(d);
        mListener.onCustomObjectFetched(d);
    }
}

}

モジュール A には、FetchCustomObjectListener.class というインターフェースも含まれています。

public interface FetchCustomObjectListener {
    public void onObjectFetched(CustomObject d);
}

モジュール B には、Startup.class というクラスが含まれています。

public class Startup {

private Startup(Context context) {
    super(context);

    Util.GetObjectTask getObjectTask = new Util.GetObjectTask(context, new FetchCustomObjectListener() {
        @Override
        public void onObjectFetched(CustomObject d) {
            //handle custom object here
        }
    });

    getObjectTask.execute();
}

実行時に、Startup クラスは GetObjectTask のインスタンスを作成して実行します。GetObjectTask はデータベースからオブジェクトを取得し、インターフェイス FetchObjectListener を介してそれを Startup クラスに返そうとします。この時点で、次のエラーが表示されます。

java.lang.AbstractMethodError: abstract method "void a.b.c.FetchObjectListener.onObjectFetched(a.b.c.CustomObject)"
at a.b.c.Util$GetObjectTask.onPostExecute(SourceFile:65)
at a.b.c.Util$GetObjectTask.onPostExecute(SourceFile:48)
at android.os.AsyncTask.finish(AsyncTask.java:632)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

私が理解しているように、このエラーは、Dexguard の実行時に、インターフェイスが 1 つのモジュールまたはクラスによって「保持」され、別のモジュールまたはクラスによって「保持」されていない場合に発生する可能性があります。したがって、1 つのモジュールには実際の名前があり、もう 1 つのモジュールには難読化された名前があります。このため、2 つのモジュールはインターフェイスを使用して通信できず、AbstractMethodError がスローされます。

過去に、私は Dexguard を使用してこのプロジェクトを正常にコンパイルおよび実行しましたが、その後、プロジェクトをさらにモジュール化し、これが問題の一部である可能性があると感じています。問題の可能性があるものを絞り込もうとしていますが、インターフェイスを使用しようとしている 2 つのモジュールが問題を引き起こしている可能性があると考えました。

これを解決する方法についてのアイデアをいただければ幸いです。

4

1 に答える 1

3

2 番目のライブラリを処理するときに、最初のライブラリのファイル フィルターが正しくないことが判明しました。最初のライブラリから欠落しているクラスに関する警告を見たことがあるかもしれません。この問題は DexGuard 6.1.15 で修正されています。

最終的なアプリケーション (ライブラリを含む) を処理する方が、個々のライブラリを処理するよりも効果的であることに注意してください。

于 2015-03-28T00:51:09.230 に答える