5

OVERVIEW:
I am facing an issue while accessing the activity of the on-demand dynamic feature module from the base module due to proguard. (most probably I guess)

DESCRIPTION:
I have implemented an ON-DEMAND dynamic feature module with app bundle and uploaded on play store.
Implemented proguard with custom rules with it.
After downloading the application from the play store and while accessing that module at runtime, the module gets downloaded. Just after downloading it, I have a call for accessing an activity from my base module to that dynamic module.
I am getting error as like below

...
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{xxx.yyyyyy.zzzzzz.stage/xxx.yyyyyy.zzzzzz.apphub.appview.view.AppHubActivity}:
java.lang.ClassNotFoundException: Didn't find class "xxx.yyyyyy.zzzzzz.apphub.appview.view.AppHubActivity"
on path: DexPathList[[zip file "/system/framework/org.apache.http.legacy.boot.jar", zip file 
...
...

FYI:
xxx.yyyyyy.zzzzzz is my changed package name for privacy.

IRONY:
This entire code is working perfectly in debugging while accessing it from the app bundle locally without proguard.

I have tried all the links below to overcome this but could not.
1) https://issuetracker.google.com/issues/120517460
2) https://github.com/android/plaid/issues/764
3) java.lang.NoClassDefFoundError:failed resolution of :Lorg/apache/http/ProtocolVersion
4) https://issuetracker.google.com/issues/79478779
5) https://github.com/android/app-bundle-samples/issues/17

I have also tried all types of proguard files which we can use, but still helpless.
Also kept that both classes in proguard: base and dynamic module activity class but got no success.
Hopefully looking for the solution here.

UPDATE:
not working in android OS 8,9 but working file in android 10.

Sanket Vekariya
  • 2,848
  • 3
  • 12
  • 34

2 Answers2

2

I started implementing dynamic feature module this month in my app and proguard was given me issues. I also didn't wanted to push my app to playstore without obfuscating the codes. So this is how i solved this with proguard enabled.

  1. Android proguard optimizer already keeps all classes that extends android.view.View. That means any class that extends the View class will not be obfuscated by proguard.

So i created a class in my featured module and extended View and overrided just the first method because it's not for view in my views hierarchy

public class YourCalssName extends View {
  public YourClassName(Context context) {
      super(context);
  }

  public static void launchActivity(Activity activity){
     activity.startActivity(new Intent(activity,YourMainActivityInYourFeatureModule.class));
}

}

But Android proguard optimizer doesn't keep method names. Only setters and getters are kept. So i added a proguard keep rule in my main app to not obfuscate static methods to classes that extends android.view.View

-keepclassmembers public class * extends android.view.View {
  public static <methods>;
}

Then i used reflection to call the static method to launch my featured module main activity

Class myClass = Class.forName("your_fully_qualified_name");//Without .class
Method method = myClass.getDeclaredMethod("launchActivity",Activity.class);
method.invoke(null, this) ;

This will keep your class name and methods that launches your featured module activity and it static methods.

Also make sure you add this code to all your activities in your featured module

@Override
protected void attachBaseContext(Context base) {
   super.attachBaseContext(base) 
   SplitCompat.installActivity(this);
}
0

Make sure you use SplitCompat in the activities of your on-demand module AND in your Application.

See https://developer.android.com/guide/playcore#access_downloaded_modules which explains in more details how to do so.

Pierre
  • 15,865
  • 4
  • 36
  • 50