Android发布/订阅Singleton示例

时间:2014-04-05 23:05:31

标签: java android android-layout android-fragments software-design

有人可以提供一个使用Publish / SUbscribe单例模式在片段之间传递信息的简单示例。上周我询问了passing data between fragments下面的情景,并提出了这种方法;我似乎无法绕过它。

  

我有一个使用导航抽屉布局的应用程序,有各种各样的   "子应用程序"执行独立功能(例如,a   计算器应用程序,与不相关的"子应用程序"所得税   计算,公制/英制转换等)。对于给定的   计算器,我有一个数据输入/选择片段和数据   演示片段,显示一些有意义的计算   方式类型。因此,我在应用程序中唯一的活动是   MainActivity,保存导航抽屉和内容窗格。该   问题是:设计应用程序的最佳方法是什么   各种计算器将数据传递给它们的数据表示   碎片,比如点击按钮?

1 个答案:

答案 0 :(得分:3)

互联网上的所有例子... ks,他们的UML图表对于初学者来说绝对不清楚,而且只有经验丰富的人才能理解为什么使用这个而不是那个,而不是另一个...所以,让我们#39 ; s逐步构建并逻辑思考。

首先,您需要在单件类中创建某种存储 - 使数据不依赖于片段'生命周期。根据您的应用程序的目的,它可能是不同类型的集合或只是基元。将这些字段添加到您的单身人士中,例如:

double conversionRate, taxRate;
int securityNumber;
.... // and so on

现在你需要一些单例的方法来更新这些数据。我们称之为updateData()。每当用户更改任何片段中的某些数据时,此片段应调用:

Singleton.getInstance().updateData(dataType, data);

作为参数,让我们放置数据类型和包含这些数据的对象。

第二,,您需要更新其他演示文稿片段中的数据,对吗?因此,此updateData()方法应该运行此刻运行的片段列表,并向每个片段发送新数据。怎么实现呢? - 非常简单,通过回调方法。为此,您需要:

1)使用一种方法创建一个Updateable公共接口:public void onUpdate(int dataType, Data data)

2)在类名

之后implements Updateable对每个片段实现此接口

3)在类体中实现其唯一的方法onUpdate()。在该实现中,每个片段将首先考虑是否需要使用给定数据类型的数据,其次,处理这些接收的数据(例如,改变其文本视图值):

@Override
onUpdate(int dataType, Data data){
   if (dataType == DATA_TAX_RATE){
      textViewTaxRate.setText(String.parseInt(data.getValue()));
   }

}

第三,您的单身人士将如何知道应该向谁发送更新的数据?非常简单:只需添加一个包含所有片段作为Updateable对象的存储空间:

List<Updateable> listeners = new ArrayList<Updateable>;

并添加两个额外的方法来注册和取消注册对象(例如你的片段)作为监听器。在第一种方法中,您应该只将侦听器添加到提到的列表中,然后将其删除:

public void registerListener(Updateable listener){
  if (!listeners.contains(listener)) {
     listeners.add(listener);
  }
}

public void unregisterListener(Updateable listener){
  if (listener != null && listeners.contains(listener)){
     listeners.remove(listeners.indexOf(listener));
  }
}

现在,每个想要接收更新的片段(即实现可更新接口)应该在创建和恢复后立即注册为监听器:

Singleton.getInstance().registerListener(this);

并在onDestroy上取消注册,或者当它不再需要监听更新时

Singleton.getInstance().unregisterListener(this);

N.B。:为防止内存泄漏,您应该在不再使用此对象时取消注册侦听器。否则对它的引用将被保存在监听器列表中,使垃圾收集器无法访问它!

在我们创建了添加和删除侦听器的方法之后,让我们回到之前提到的单例方法updateData()。它的主要目的是存储新数据并向所有听众发送更新,所以让我们实现它:

public void updateData(int dataType, Data data){
   // store new data
   if (dataType == DATA_TAX_RATE){
       this.taxRate = data.getValue();
   }

   .....

   // then iterate through listeners and send updated data to them
   for (Updateable listener : listeners){
       try {
          listener.onUpdate(dataType, data);
       } catch (Throwable e) {}
   } 
}

现在,每当用户更新任何片段中的某些数据,或者通过计算更新数据时,只需从此片段中调用Singleton.getInstance().updateData(...) - 新数据将以单身形式存储,并自动广播到其他片段。

=============================================== ===================

免责声明:这不是Observer设计模式的精确实现,只是它的简化版本对于初学者来说更清晰易懂。这就是为什么我不使用诸如Observernotify之类的通用名称等等。这只是为了更深入地理解常见设计模式的第一步而举的典范。< / em>的