【问题标题】:Get application context from non activity singleton class从非活动单例类获取应用程序上下文
【发布时间】:2014-03-16 03:33:43
【问题描述】:

在我的 android 项目中,我有 ImageAdapter 类,我在其中传递应用程序上下文以满足进一步的需求。

public class ImageAdapter extends BaseAdapter {
    private Context c;

    public ImageAdapter(Context c) {
            this.c = c;
    }
    ...
}

问题是我想让 ImageAdapter 成为一个单例,以便从我的所有活动中轻松访问此类的实例。但我不知道如何将应用程序上下文从我的一项活动的 getApplicationContext() 方法传递到 ImageAdapter。那么有没有什么“魔法”可以做到以下几点?

public class ImageAdapter extends BaseAdapter {

    private Context c;

    private static class Holder {
            public static final ImageAdapter IA = new ImageAdapter();
    }

    private ImageAdapter() {
            this.c = /* some magic here */.getApplicationContext();
    }

    public static ImageAdapter getInstance() {
            return Holder.IA;
    }
    ...
}

也许你有一些其他的想法来分享我的任何活动的 ImageAdapter。 我是 android 的新手,我对在活动之间传递数据的方式有点困惑。

如果有任何帮助,我将不胜感激。

【问题讨论】:

  • 您在问题中说“我想让 ImageAdapter 成为单例,以便从我的所有活动中轻松访问此类的实例。”您如何轻松访问 imageadapter 类的实例并使用你们所有的活动,请详细说明我想增加我对它的了解

标签: java android singleton baseadapter android-context


【解决方案1】:

更新:2018 年 3 月 6 日

使用MyApplication 实例而不是Context 实例。 Application 实例本身就是一个单例上下文实例。

public class MyApplication extends Application {

    private static MyApplication mContext;

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

    public static MyApplication getContext() {
        return mContext;
    }
}

上一个答案

您可以像这样获取应用程序上下文:

public class MyApplication extends Application {

    private static Context mContext;

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

    public static Context getContext() {
        return mContext;
    }
}

然后,您可以从方法MyApplication.getContext()调用应用程序上下文

不要忘记在清单文件中声明应用程序:

<application
    android:name=".MyApplication"
    android:icon="@drawable/icon"
    android:label="@string/app_name" >

【讨论】:

  • 顺便说一句,应用程序应用程序上下文; getApplicationContext() 可以替换为 this。 (getApplicationContext 存在,因此如果您有 any 上下文,则可以访问应用程序。)代码没有错,只是指出这一点。
  • 不建议将 Android 上下文类放在静态字段中。静态字段会泄漏上下文——Android Studio 也会警告这个问题。
  • 这个答案是否仍然是最新的?因为编译器说“不要将 Android 上下文类放在静态字段中;这是内存泄漏(也会破坏 Instant Run)
  • @JimClermonts 我知道自从您提出问题以来答案已经更新,但更新后的答案不应给出任何警告。不同之处在于Context 可以是任何上下文,包括活动(不时被销毁)。通过指定它是 Application 对象(只要应用程序存在)就不应该有任何问题
  • 这仍然是真实的吗?
【解决方案2】:

我宁愿将上下文实例作为参数传递给单例中真正需要它的每个方法

【讨论】:

  • 没办法,我需要覆盖方法中的上下文 @Override public View getView(int position, View convertView, ViewGroup parent) 据我所知它会自动触发。
【解决方案3】:

方法 #1:

由于您指定 ImageAdapter 是单例,一个简单的答案是从可以访问应用上下文的类创建该单例:

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        ImageAdapter.createIt(this);
    }
}

public class ImageAdapter extends BaseAdapter {
    private static ImageAdapter it;
    // Get the singleton.
    public static ImageAdapter getIt() {
        return it;
    }
    // Call this once, to create the singleton.
    public static void createIt(Context context) {
        it = new ImageAdapter(context);
    }

    private final Context c;
    private ImageAdapter(Context context) {
        c = context;
    }
}

方法 #2:

如果不是单例,那么我会使用接受的答案。在这种情况下,请从 ImageAdapter 中删除局部变量,因为始终可以从 MyApplication 获取上下文。扩展已接受的答案,如果您想要一个方便的本地方法,请定义 ImageAdapter.getContext()。完整的解决方案:

public class MyApplication extends Application {
    private static Context appContext;
    public static Context getContext() {
        return appContext;
    }

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

public class ImageAdapter extends BaseAdapter {
    public ImageAdapter() {
    }

    // [Optional] Call this whenever you want the app context.
    private Context getContext() {
        return MyApplication.getContext();
    }
}

【讨论】:

    猜你喜欢
    • 2014-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-29
    • 2013-07-28
    相关资源
    最近更新 更多