将 ProGuard / Dexguard 与多个 Android Studio 模块一起使用

Using ProGuard / Dexguard with multiple Android Studio Modules

我有一个 Android Studio android 项目,其中包含两个模块,模块 A 和模块 B。我正在构建和测试这些模块,然后将它们作为 .aar 文件分发。当使用 .aars 运行s 的父应用程序时,我遇到了 AbstractMethodError,我不知道为什么。我在两个模块的 dexguard-project.txt 文件中包含了 classes 和接口的 -keep 标志,希望它能工作但无济于事。以下是有关该项目的更多信息:

模块 A 包含一个名为 Util.class 的 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:

的 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 class 创建了一个 GetObjectTask 实例并执行它。 GetObjectTask 从数据库中抓取一个对象并尝试通过接口 FetchObjectListener return 将其 class 启动。此时我收到以下错误:

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.access0(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)

据我了解,当一个接口被一个模块 'kept' 或 class 而不是另一个模块 'kept' 而 Dexguard 是 运行 时,可能会发生此错误。因此,一个模块具有实际名称,一个具有混淆名称,因此这两个模块无法使用接口进行通信,因此抛出 AbstractMethodError。

过去我曾使用 Dexguard 成功编译和 运行 这个项目,但此后对项目进行了更多模块化,感觉这可能是问题的一部分。我正在尝试缩小可能出现问题的范围,并认为可能是两个模块试图使用一个接口导致了问题。

任何关于如何解决这个问题的想法都将不胜感激。

原来是在处理第二个库时对第一个库的文件过滤不正确。您可能已经从第一个库中看到关于缺少 类 的警告。该问题已在 DexGuard 6.1.15 中修复。

请注意,如果可以选择,处理最终应用程序(包括其库)比处理单个库更有效。