【问题标题】:Create application class dynamically in Android在 Android 中动态创建应用程序类
【发布时间】:2020-04-21 22:06:36
【问题描述】:

我有一个第三方库,它通过侦听器接口公开其功能。该库的要求是它在自定义 Android 应用程序类的 onCreate 中进行初始化。

public class CustomApplicationWithListener extends Application implements ThirdPartyListener {
   public void onCreate() {
     if(feature.isTurnedOn()){
       // the library requires an application instance of type ThirdPartyListener
       init(this);
     }
   }
}

我试图将这个功能隐藏在一个特性标志后面,并且想知道是否有一种方法可以从应用程序类中抽象出监听器,并且只在需要该特性时才定义它。只有这样我们才声明该接口。我知道需要在清单中定义自定义应用程序类。有没有办法在运行时动态决定是否启用该功能,然后使用如下所示的第三方侦听器初始化基本自定义应用程序对象,并让主清单知道我们将要使用的版本?

var application: Application?
if(feature.isTurnedOn()){
 application = CustomApplicationWithListener()
} else {
 application = CustomApplication
}

【问题讨论】:

  • 你到底想达到什么目的?您的目标是在运行时切换它还是使用单个代码库拥有两个版本的应用?
  • 在 Android 9.0 及更高版本上,您可以使用 AppComponentFactory 创建您的 Application 的自定义实例。但是,由于您的应用程序的其余部分未设置,您将不知道功能标志值是什么。为什么你让你的Application 类实现这个接口,而不是让它在其他对象上实现?
  • 如果我在其他类中实现接口,我会得到一个运行时异常,说该库需要在应用程序 oncreate 中初始化,并且需要一个侦听器类型的应用程序实例!通过此处的功能标志,我正在读取客户端上的标志,我没有达到任何端点来决定是否要显示该特定功能。它是一个编译时标志
  • @CommonsWare Android 9.0 之前的版本支持AppComponentFactory
  • @luckysing_noobster:不,抱歉。

标签: java android oop kotlin android-application-class


【解决方案1】:

在运行时在 android 应用程序中生成代码并不是一件容易的事,可以使用Reflection 来完成。查看 Java 的 Reflection API 以了解反射的工作原理。

另一方面,编译器时的代码生成并不难,Annotation Processors 可以实现。参考这篇博文了解how annotation processors work

查看允许用户按需下载特定功能的动态模块。这可能是最适合您的情况的解决方案。设置具有功能标志视图的 PreferenceFragment 并通过解决方案中的 SharedPreferences 读取值。

我仍然质疑你为什么不想在你的类应用程序中声明 3rd 方库。许多第 3 方库通常需要在基础应用程序类中进行实例化。如果库依赖是您的答案,那么可以通过将自己的应用程序拆分为表示、数据和域模块来解决。这至少会将 android 框架与您的业务逻辑隔离开来。

【讨论】:

  • 您可能想要编辑您的答案以解释这与功能标志如何控制Application 实例化有什么关系。
  • @CommonsWare Well 功能标志无济于事,因为应用程序实例化将在生成 PreferenceFragment 之前进行。所以应用程序 onCreate 已经被执行了。但是,使用 sharedPreferences 重新初始化应用程序可能会解决此问题。在这种情况下,OP 如果有兴趣可以参考此评论。
  • “应用程序实例化将在 PreferenceFragment 生成之前发生”——请注意,该问题不涉及 PreferenceFragment。 “使用 sharedPreferences 重新初始化应用程序可能会解决这个问题”——请注意,无论是问题还是您的答案,都不是指SharedPreferences
  • @CommonsWare PreferenceFragment 仅用于引用功能标志视图被夸大的地方。因为这样做最合乎逻辑的地方是PreferenceFragment,因此有这样的提及。此外,恢复应用程序并不是一个好的用户体验,因此它没有包含在不推广它的答案中,以及评论中提到它的原因,对于那些好奇的人。
  • @CommonsWare 在答案中更明确地说明了功能标志视图如何解决问题。此外,通过服务器提供功能标志可能不是一个好主意,因为这将需要 apk 包含不必要的资产,这些资产将保持未使用并增加 apk 大小。如果遵循动态功能模块方法来获取某些初始“必须”功能集,然后让 android app bundle 在需要时提供它们,这总是一个好主意。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-22
  • 1970-01-01
相关资源
最近更新 更多