获得应用程序上下文

26

这可能是一个简单的问题,但我只想确保我是正确的。

在我的Android应用程序中,我有一个使用以下内容的构造函数:

activity.getApplicationContext()
活动被作为参数传递到构造函数中。
问题是我从服务中调用这个类。如果我创建另一个构造函数,它接受服务作为参数并使用service.getApplicationContext,那么我会得到相同的应用程序上下文吗?

我有一个非常类似的问题 - 我有一个具有多个进程的应用程序。有一个库需要一个类加载器,但它本身不是一个应用程序,而是在应用程序中使用。它可能在应用程序的多个进程中。是否有一种方法可以从库中获取当前进程的上下文,使用任何进程中可访问的全局对象,以便我可以调用context.getClassLoader()? - peterk
6个回答

58

获取应用上下文最简单的方法是:

创建一个名为App、继承自android.app.Application的类。

public class App extends Application {
    public static Context context;

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

修改你的AndroidManifest.xml文件中的<application>标签,将属性android:name="your.package.name.App"添加进去。

每当你需要应用程序的上下文时,只需从App.context获取即可。

Application始终是最先初始化的,无论你的进程运行方式是活动、服务或其他类型。你将始终可以访问应用程序上下文。


5
我曾在某处看到完全相同的方法,并将其用于使应用程序上下文在整个应用程序中可访问。但我不确定,这是否是实现此目的的最佳做法?为什么访问应用程序上下文不作为Android SDK的内置功能提供? - Alireza Mirian
1
如你所说,getApplicationContext是Context类或其子类的一个方法。但是假设你正在创建一个覆盖AsyncTask的类来在应用程序中执行一些操作,并且你想在onPostExecute中操纵UI。无论如何,如果getApplicationContext是静态的,我认为生活会更加轻松。 - Alireza Mirian
11
Android Studio对这段代码发出警告 - “不要将Android上下文类放入静态字段中; 这会导致内存泄漏(并且还会中断即时运行)”。这真的是实现全局上下文变量的最佳方法吗? - Neo
3
这是一个内存泄漏。 - Logan Guo
3
应用程序尚未初始化,内容提供者在其之前初始化。 - BladeCoder
显示剩余4条评论

13

我会得到相同的应用程序上下文吗?

是的。您可以查看Android文档,它们已经提供了。

 getApplicationContext()

返回当前进程单一全局 Application 对象的上下文。

因此,它应该在整个应用程序进程中保持不变。

请注意:

getApplicationContext() 通常仅在需要一个生命周期与当前上下文分离、与进程寿命而非当前组件寿命相关联的 Context 时使用。

如有错误,请指正。

谢谢。


2

只有一个应用程序上下文,因此您应该获得相同的上下文。您可以只拥有一个构造函数,它需要一个Context,您不需要两个。或者,如果您想确保获取的是应用程序上下文,而不是活动上下文,则可以使您的构造函数采用Application作为参数,这是一个Context


1
我已经根据yuku的回答进行了修改,使用非静态直接上下文引用。
创建一个类domain.company.pseudo.ApplicationName,它扩展android.app.Application
package hypersoft.systems.android;

import android.app.Application;

public class Starbox extends Application {

  public static Starbox instance;

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

}

在此示例中,我的完整应用程序包名称是 hypersoft.systems.android.starbox
现在,修改您的 AndroidManifest.xml <application> 标签,使其具有属性 android:name="hypersoft.systems.android.Starbox",并确保 Starbox.java 类文件位于项目组件目录:android 而不是 starbox
完成所有这些步骤后,您现在可以 import hypersoft.systems.android.Starbox,并在您的代码中通过调用 Starbox.instance.getApplicationContext() 来获取 ApplicationContext
使用构建工具 26 和 api 26(Android 8.0)成功编译,最低 sdk 版本为 14(4.0)。

我很感兴趣知道哪种方法在这里是更好的实践。因为当我们只需要和使用上下文时,我看不到将整个应用程序对象公开给整个项目的优势。考虑到这种用例,是否有必要或更好地提供整个应用程序对象,而不仅仅是所需/使用的组件或函数? - Benjamin Basmaci

1

如果您想获取整个应用程序的上下文,请使用getApplicationContext()。如果您想要获取当前类的上下文,则可以使用getBaseContext()


-2

Application Context和Activity Context是不同的。向下转型是有风险的。使用以下代码来使用context对象。

public class App extends Application {
public static Context context;

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

在您的活动和片段类中: < p > < code > Conetext context=App.context;


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