I have an Android Studio android project with two modules, Module A and Module B. I am building and testing these modules and then distributing them as .aar files. When the parent app that uses the .aars runs I am encountering an AbstractMethodError and I can't figure out why. I have included -keep flags for classes and interfaces in the dexguard-project.txt files of both modules in the hopes that it would work but to no avail. Here's more information about the project:
Module A contains a class called 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);
}
}
}
Module A also contains an interface called FetchCustomObjectListener.class
public interface FetchCustomObjectListener {
public void onObjectFetched(CustomObject d);
}
Module B contains a class called 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();
}
At runtime the Startup class creates an instance of GetObjectTask and executes it. GetObjectTask grabs an object from the database and tries to return it to Startup class via the interface FetchObjectListener. At this point I am getting the following error:
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)
As I understand it, this error can occur when an interface is 'kept' by one module or class and not 'kept' by another when Dexguard is run. So one module has the actual name and one has the obfuscated name and because of this the two modules can't communicate using the interface and so the AbstractMethodError is thrown.
In the past I have used Dexguard to successfully compile and run this project, but have since modularized the project more and feel that this may be part of the problem. I'm trying to narrow down what could possibly be a problem and thought that perhaps two modules trying to use an interface might be causing the problem.
Any ideas on how to solve this would be appreciated.