给我的 class 一个静态的 getInstance(Context)

Giving my class a static getInstance(Context)

假设我有一个 class 想要通过静态方法提供其自身的实例。这些实例需要使用 Context,因此该方法将这样调用:

Foo foo = Foo.getInstance(context);

我正在考虑这样做:

public class Foo {
    private static final Map<Context, Foo> instances = new WeakHashMap<>();
    private final WeakReference<Context> weakContext;

    private Foo(Context context) {
        if(context == null) throw new NullPointerException();
        weakContext = new WeakReference<Context>(context);
    }

    public static Foo getInstance(Context context) {
        Foo instance = instances.get(context);
        if(instance == null) {
            instance = new Foo(context);
            instances.put(context, instance);
        }
        return instance;
    }
}

首先,这行得通吗?其次,为什么我总觉得自己多虑了?

您似乎想要缓存 Foo。当我需要缓存时,我希望它不在我的模型中。

也许你只需要一个工厂,你可以把Map<Context, Foo> instances放在工厂里。

经过更多考虑,我会说我问题中的代码要么毫无意义地复杂,要么需要进一步完善,具体取决于 Foo 是否需要做应用程序无法完成的事情上下文。

如果是,那么我的 getInstance(...) 看起来与我最初写的类似,除了 Context 它应该需要更具体的类型,例如 getInstance(Activity)

如果没有,那么我可以省去Map。该实例可以是伪单例并使用应用程序上下文。

This article 包含一个 table 显示您可以使用不同类型的上下文做什么。

您所描述的情况是android系统服务的设计方式。 根据提供的上下文,确定服务的可用性和功能。 如果您想根据上下文提供不同的功能,那么您可以查看它们的实现。

然而,要记住的重要一点是上下文也有层次结构。因此,如果您获得 activity 上下文,您还可以获得应用程序上下文。

保持上下文的弱引用也可能适得其反:

假设您对 ActivityA 的引用较弱,但当前处于 ActivityB,您现在需要一个 ActivityB 上下文。 所以通常的单例模式应该在这里满足你的目的。如果您正在尝试更复杂的功能,他们提供的用例可能会让您获得更有针对性的答案。