在Android库中获取上下文

19

我正在编写一个Android应用程序,其中一些功能被封装在一个内部库中。 然而,为了使这些功能正常工作,该库需要应用程序上下文的实例。 给库提供上下文的最佳方法是什么? 我看到了几个选项,但都不太理想:

  • 让我的库类扩展Application,然后调用getApplicationContext()
    • 通常不建议这样做。
  • 让我的库类每个都实现单例模式,并在每次获取单例引用时让每个调用者传递一个Context
    • 这要求每个调用者在使用库之前检索应用程序上下文,并且还要求调用者针对库类定义的静态方法进行调用(因此进一步需要保留对该实例的引用)。
4个回答

14
什么是给库传递Context的最佳方法?
通过将Context传递给库中需要Context的方法。这是Android SDK在某些位置所做的方式。
或者,将您的库更改为公开对象而不是静态方法,并让这些对象持有Context实例(由构造函数或创建该实例的工厂方法提供)。
如果您可以在Context上调用getApplicationContext(),则只需这样做,而无需子类化Application。

嗨@CommonsWare,感谢您的回答,但您能详细说明一下“这不会起作用”是什么意思吗?据我所知,它应该可以工作,但只要您已经有一个对上下文的引用,扩展应用程序就是不必要的,对吧?感谢您的时间 :) - TheIT
2
@TheIT:是的,那句话措辞不当,我已经修正了。对于造成的困惑,我深表歉意。顺便说一下,既然你似乎专注于“应用程序”,如果你还没有这样做,你可能想阅读戴夫·史密斯关于选择正确“上下文”的卓越文章:http://www.doubleencore.com/2013/06/context/,“应用程序”确实是正确的答案,特别是如果你需要一个从静态数据成员引用的“上下文”,但通常在不适当的情况下使用它。 - CommonsWare
非常感谢您的更新和提供有用链接,我们非常感激! - TheIT

10

这是我发现的一个解决方案,虽然我没有测试过,但显然由 Firebase 使用以避免创建 init 方法:

“应用程序启动时会发生什么是在系统中注册所有 ContentProviders(调用 onCreate)。这意味着此时还没有启动任何活动,但我们可以访问(应用程序)上下文,在这里使用此上下文初始化我们的库”

本质上,您正在利用空 ContentProvider 的 onCreate 作为 init。 这是一个 hacky 的方法,但是无缝的。

https://medium.com/@andretietz/auto-initialize-your-android-library-2349daf06920


3

我不确定这种情况的最佳实践,但我想在应用程序创建期间在我的单例类中设置上下文。

MyLibrary.init(this);

为什么要这样做?如果您之前使用过Crashlytic/Fabric,您会发现它们正在使用

Fabric.with(this, new Crashlytics());

如果你查看 Fabric 的代码,你会发现他们将上下文信息存储在 Fabric 单例中。

Facebook Android SDK 也做了类似的事情:

FacebookSdk.sdkInitialize(getApplicationContext());

如果您浏览它们的代码,会发现它们存储静态上下文。
那么,什么是最佳实践呢?我不确定,但我相信这些优秀的开发者创造了优秀的库,并在发布这些库之前进行过讨论。无论如何,我仍在学习如何编写最佳的Android库,并遇到了这些主题。

1

App Startup 库是 Android Jetpack 的一部分。它允许在不使用多个 ContentProviders 的情况下监听应用程序启动。此外,它还提供了处理依赖树的能力。

实现示例


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接