【问题标题】:Getting the Application Context获取应用程序上下文
【发布时间】:2011-10-31 22:21:51
【问题描述】:

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

在我的 android 应用程序中,我有一个构造函数,它使用:

activity.getApplicationContext()

活动作为参数传递给构造函数。

问题是我从服务调用这个类。如果我创建第二个构造函数,它接受服务作为参数并使用service.getApplicationContext?我会得到相同的应用程序上下文吗?

【问题讨论】:

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

标签: android android-activity service android-context


【解决方案1】:

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

创建一个扩展 android.app.Application 的类 App

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 无论您的进程是否运行,无论是活动、服务还是其他东西,总是首先初始化。您将始终可以访问应用程序上下文。

【讨论】:

  • 我在某处看到了完全相同的方法,我正在使用它来使整个应用程序都可以访问应用程序上下文。但我不确定,这是实现这一目标的最佳做法吗?为什么访问应用程序的上下文没有作为 android SDK 的内置功能提供?
  • getApplicationContext 如您所说是Context 类或其子类的方法。但是假设您正在创建一个覆盖AsyncTask 的类来在您的应用程序中做一些事情。例如,您想在onPostExecute 中操作 UI。无论如何,如果getApplicationContext 是静态的,我认为生活会更轻松。
  • 我觉得这应该是公认的答案。干净优雅!
  • Android Studio 对此代码发出此警告 - Do not place Android context classes in static fields; this is a memory leak (and also breaks Instant Run) 。这真的是实现全局上下文变量的最佳方式吗?
  • 这是内存泄漏
【解决方案2】:

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

是的。你可以查看android文档,他们提供了

 getApplicationContext()

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

所以整个申请过程不应该改变。

还请注意这一点:

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

如果我错了,请纠正我。

谢谢

【讨论】:

    【解决方案3】:

    只有一个应用程序上下文,所以你应该得到相同的。您可以只有一个带有Context 的构造函数,实际上并不需要两个。或者,如果您想确保获取的是应用程序上下文,而不是活动上下文,您可以让构造函数将Application 作为Context 的参数。

    【讨论】:

      【解决方案4】:

      如果你想获得整个应用程序的上下文,你可以去getApplicationContext()。如果你想获取当前类的上下文,你可以使用getBaseContext()

      【讨论】:

        【解决方案5】:

        我已经用非静态直接上下文引用改编了 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

        使用最小 SDK 版本 14 (4.0) 的构建工具 26 和 api 26 (Android 8.0) 成功编译。

        【讨论】:

        • 我对哪种方法是更好的做法感兴趣。因为当所有人都需要和使用上下文时,我看不到将整个应用程序对象显示给整个项目的好处。考虑到该用例,是否仍然有必要或更好地提供整个应用程序对象,而不是只提供需要/使用的组件或功能?
        【解决方案6】:

        Application Context add Activity Context 两者不同。向下转换有风险。使用此代码使用上下文对象。

        public class App extends Application {
        public static Context context;
        
            @Override public void onCreate() {
                super.onCreate();
                context = getApplicationContext();
            }
        } 
        

        在您的活动和片段类中:

        Conetext context=App.context;

        【讨论】:

          猜你喜欢
          • 2010-09-12
          • 1970-01-01
          • 2014-03-26
          • 2019-10-19
          • 1970-01-01
          • 1970-01-01
          • 2013-12-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多