在库中使用上下文的单例(aar)

时间:2017-03-02 10:52:29

标签: android singleton aar

我有一个需要上下文应用程序的库(aar),因为它使用了一些需要上下文的API方法(例如WifiManager)。

我看到了there,在许多其他主题中,实现这一点的常见方法是将Context作为参数传递给我需要它的lib对象。 我在阅读this文章时遇到了问题。 lib将由外部客户端使用,所以我想不惜一切代价避免所有空指针异常(你知道规则:如果它发生,它将在某个时刻发生)。

我们说我的库中有一个主入口点,这个类是Singleton并保存上下文(在ctor中或通过setter)。我想要这个班级来主持" Context和行为有点像Application类:它将为我的库的其他类提供上下文。

如何从" children"中访问此单例类?类或其他类遵循nfrolov的文章中描述的原则?

让我们看一些(伪)代码,其中包含MainSingletonNetworkManager(单身)和DataProvider

DataProvider可以是MainSingleton的成员,也不需要上下文,但NetworkManager需要上下文才能使用WIFI_SERVICEregisterReceiver方法

但是,DataProvider需要来自NetworkManager的信息,要么通过向其注册监听器,要么从MainSingleton获取数据(用作事件总线之间的数据来协调儿童课程,就像我们可以使用活动和多个片段一样)。

案例1

public class MainSingleton
{
    private static MainSingleton instance = new MainSingleton();
    private static Context context = App.getAppContext(); // where the frog do I get that from ?

    ...
}

问题:由于这是主要的切入点,我无法访问" App"在这里,所以它应该作为一个参数传递给某个地方,作为一个setter。但是上下文被初始化为null?

案例2

public class MainSingleton {
    private static MainSingleton instance = null;

    private Context context;

    private MainSingleton(Context context) {
        this.context = context;
    }

    public synchronized static MainSingleton getInstance(Context context) {
        if (instance == null) {
            instance = new MainSingleton(context.getApplicationContext());
        }

        return instance;
    }
}

问题:每个孩子"需要调用MainSingleton类的实例也需要一个上下文。

修改

阅读this帖子后:我很可能会认为,当嵌入我的aar的客户端应用程序正在运行时,我的MainEntryPoint永远不会被卸载,将Context作为参数传递给init方法并保持静态。

1 个答案:

答案 0 :(得分:0)

public class ConsumerManager {

   private static final ConsumerManager CONSUMER_MANAGER = new ConsumerManager();
   private Context context;

   public ConsumerManager() {
   }

   public static ConsumerManager getConsumerManager() {
       return CONSUMER_MANAGER;
   }

   public synchronized void initialize(Context context) {
       this.context= context;
   }

   public boolean isNetworkAvailable() {
    ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
    return activeNetworkInfo != null && activeNetworkInfo.isConnectedOrConnecting();
   }
}

首先,你需要从活动中调用它。

ConsumerManager.getConsumerManager.initialize(this);

从您需要致电的任何地方检查网络可用性

ConsumerManager.getConsumerManager.isNetworkAvailable();

[EDITED]不要将Android上下文类放在静态字段中(对具有指向Context的字段活动的ConsumerManager的静态引用);这是一个内存泄漏(也打破了Instant Run)