5

概述:
由于 proguard,我在从基本模块访问按需动态功能模块的活动时遇到问题。(很可能我猜)

描述:
我已经实现了一个带有应用程序包的按需动态功能模块,并上传到了 Play 商店。
用它实现了带有自定义规则的proguard。
从 Play 商店下载应用程序并在运行时访问该模块后,该模块将被下载。刚下载完之后,我就要求从我的基本模块访问一个活动到那个动态模块。
我收到如下错误

...
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 
...
...

仅供参考:
xxx.yyyyyy.zzzzzz 是我更改的包名以保护隐私。

IRONY:
整个代码在调试中完美运行,同时从本地应用程序包访问它,无需 proguard

我已经尝试了下面的所有链接来克服这个问题,但不能。
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/协议版本
4) https://issuetracker.google.com/issues/79478779
5) https://github.com/android/app-bundle-samples/issues/17

我也尝试过我们可以使用的所有类型的 proguard 文件,但仍然无能为力。
还将这两个类都保留在proguard中:基础和动态模块活动类,但没有成功。
希望在这里寻找解决方案。

更新:
在 android OS 8,9 中不工作,但在 android 10 中工作文件。

4

2 回答 2

2

这个月我开始在我的应用程序中实现动态功能模块,proguard 给了我一些问题。我也不想在不混淆代码的情况下将我的应用程序推送到 Playstore。所以这就是我在启用 proguard 的情况下解决这个问题的方法。

  1. Android proguard 优化器已经保留了所有扩展 android.view.View 的类。这意味着任何扩展 View 类的类都不会被 proguard 混淆。

所以我在我的特色模块中创建了一个类并扩展了 View 并仅覆盖了第一个方法,因为它不适用于我的视图层次结构中的视图

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

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

}

但 Android proguard 优化器不保留方法名称。只保留 setter 和 getter。所以我在我的主应用程序中添加了一个 proguard 保留规则,以不混淆静态方法到扩展 android.view.View 的类

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

然后我使用反射调用静态方法来启动我的特色模块主要活动

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

这将保留您的类名和启动特色模块活动的方法及其静态方法。

还要确保将此代码添加到特色模块中的所有活动中

@Override
protected void attachBaseContext(Context base) {
   super.attachBaseContext(base) 
   SplitCompat.installActivity(this);
}
于 2021-11-10T10:27:11.250 回答
0

确保在按需模块的活动和应用程序中使用 SplitCompat。

请参阅https://developer.android.com/guide/playcore#access_downloaded_modules,其中详细说明了如何执行此操作。

于 2020-02-14T09:40:20.920 回答