在Android库项目中获取应用程序上下文是否可行?

71

我希望能在我的库项目的一个类中获取引用/运行时托管了我的库的应用程序上下文。这是否可能?如果是,如何实现?

谢谢。

更新 我不希望我的用户通过参数传递上下文到我的库项目中,因为我的库项目可能通过JNI被调用,而我不知道如何在JNI中获取上下文并将其传递给Java层。


如果您在其他项目中使用您的库,则您的库的上下文将是该项目的上下文。您想对上下文做什么? - Aracem
@WarrenFaith:我的Android库项目中没有这样的方法可用。 - Haris Hasan
1
@Aracem:我需要在库项目中获取上下文以执行某些操作,但我不想要求用户在某个参数中显式地传递上下文。如何能够独立获取当前应用程序的上下文到我的库中? - Haris Hasan
1
不,我的类没有继承Activity,它只是一个简单的普通类。 - Haris Hasan
1
@Haris,如果你的类是普通类,就必须显式地传递上下文。 - Blundell
显示剩余3条评论
5个回答

58

还有一种方法,可以在你的库项目中添加application类:

/**
 * Base class for those who need to maintain global application state.
 */
public class LibApp extends Application {

  /** Instance of the current application. */
  private static LibApp instance;

  /**
   * Constructor.
   */
  public LibApp() {
    instance = this;
  }

  /**
   * Gets the application context.
   * 
   * @return the application context
   */
  public static Context getContext() {
    return instance;
  }

}

然后在您的常规项目中,使真正的应用程序类扩展LibApp:

/**
 * Base class for those who need to maintain global application state.
 */
public class App extends LibApp {

  @Override
  public void onCreate() {
    super.onCreate();
  }

}

请确保在AndroidManifest文件中定义了"Name":

<application android:name="App" ...>

假设你的App类位于基础包中。

然后,您可以在库项目中使用LibApp.getContext()来获取使用库的应用程序的应用程序上下文。

这可能不是好的解决方案,但它适用于我。我分享它是因为它可能对其他人有用。


3
嗨!抱歉,但我认为这个回答涉及到了一个不同的问题。@Haris-Hasan 想要的是在库内部访问库外的一个类。也许是库中的某个方法想要访问一个继承类的资源或者类似的情况。无论如何,你的回答对于单例模式是一个很好的回答 :P - Dani bISHOP
8
他说:“我希望能够在我的库项目中的一个类内部获取运行时引用/托管我的库的上下文应用程序的上下文信息。这是否可能?如果是,怎么做?” 这段代码正好可以实现该功能,它可以访问使用该库的应用程序的上下文信息。 - peceps
1
我想这可能是一种解释方式。我在自己的库中有与您发布的相同的代码,并且它可以解决问题...如果您可以从库中定义您的类。我认为Haris-Hasan想要从库内部访问“任何东西”。无论如何,如果可访问,@peceps的回答是最简单的方法。一个通用的答案可能意味着反射,也许? - Dani bISHOP
抱歉打扰一下,但是应用程序类需要在基本包中吗? - Maxrunner
1
强制库的用户从您的类继承“Application”是一种不好的做法 - 它会创建多重继承问题,并需要为库集成创建额外的类。在这里最好的方法是拥有某种“init”方法,该方法将具有“Context”参数。 - Luten
显示剩余5条评论

14

这是可能的吗?

是的。

如果可以,怎么做?

将它作为参数传递。

我不想让用户通过参数传递上下文到我的库项目中,因为我的库项目可能会通过JNI调用,并且我不知道如何在JNI中获取上下文并将其传递到Java层。

那就弄清楚“如何在JNI中获取上下文并将其传递到Java层”。我认为你可以像传递其他对象一样进行传递。正如@Blundell所指出的,你确实没有其他选择。


3
简而言之,在 Android 库项目中独立获取应用程序上下文是不可能的。 - Haris Hasan
2
是的,对于扩展应用程序或活动的类来说是可能的。但对于任何普通的Java类(包括在正常的Android项目或库项目中的类),它是不可能独立存在的。你必须将它作为参数传递,正如我们一直在说的那样。 - Blundell

13

在jni中获取上下文的另一种方法是使用android api,而不是传递参数或自己保存上下文。 我发现源代码中有一个名为:

  • android.app.AppGlobals

的类。静态函数

  • getInitialApplication

    可以返回Application对象。但必须在主线程中调用,并且该类是隐藏的。 无论如何,您都可以通过在Java中反射来使用它。您只需使用FindClass()FindStaticObjectMethod()查找方法并使用它。希望这有所帮助。


伙计,你现在是我的个人英雄。非常感谢你。我正在制作一个Android库,用于持久性任务,应该完全可重用,没有任何依赖关系从项目到库,所以我不能只是在我的库中创建一个Application类并将其硬编码到我的清单中,那将完全破坏可重用性,并在我想将库移植到其他项目时导致不兼容问题。此外,我计划尽快发布为开源,这意味着它不能强制其他人使用库应用程序类。谢谢。 - Gabo Alvarez
访问隐藏类在Android 9.0+上被阻止了。 - CommonsWare

3
根据这篇文章,你可以通过使用ContentProvider来使库自动初始化应用程序上下文。
无论如何要小心,就像评论中描述的那样,可能会存在加载时间、即时运行以及多进程应用程序崩溃等方面的缺陷。
希望对你有所帮助。

1
我会将它作为参数传递,或者在该库中传递一个单例。
将主应用程序扩展到库的应用程序类是一个不好的想法,因为在Java中你只能从一个类继承一次。如果你的应用程序需要传递给另一个库,你会遇到麻烦。

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