Java Android发布/订阅单例
有人能提供一个使用发布/订阅单例模式在片段之间传递信息的简单示例吗。上周,我询问了以下场景,并建议使用此方法;我似乎不能把我的头围绕着它 我有一个使用导航抽屉布局的应用程序,具有各种 执行独立功能的“子应用程序”(例如 计算器应用程序,与所得税无关的“子应用程序” 计算、公制/英制换算等)。一定要 计算器,我有一个数据输入/选择片段和一个数据 以某种有意义的方式显示计算的表示片段 方式的类型。因此,我在应用程序中的唯一活动是 MainActivity,握住导航抽屉和内容窗格。这个 问题是:设计应用程序的最佳方法是什么 各种计算器将数据传递给它们的数据表示形式 碎片,比如说点击一个按钮Java Android发布/订阅单例,java,android,android-layout,android-fragments,software-design,Java,Android,Android Layout,Android Fragments,Software Design,有人能提供一个使用发布/订阅单例模式在片段之间传递信息的简单示例吗。上周,我询问了以下场景,并建议使用此方法;我似乎不能把我的头围绕着它 我有一个使用导航抽屉布局的应用程序,具有各种 执行独立功能的“子应用程序”(例如 计算器应用程序,与所得税无关的“子应用程序” 计算、公制/英制换算等)。一定要 计算器,我有一个数据输入/选择片段和一个数据 以某种有意义的方式显示计算的表示片段 方式的类型。因此,我在应用程序中的唯一活动是 MainActivity,握住导航抽屉和内容窗格。这个 问题是:设计应
互联网上的所有例子都是,初学者完全不清楚它们的UML图,大量的代码只有有经验的人才能理解为什么使用这个而不是那个,一个而不是另一个。。。所以,让我们一步一步地构建移动,并进行逻辑思考 首先,您需要在singleton类中创建某种类型的存储—使数据不依赖于片段的生命周期。根据应用程序的用途,它可能是不同类型的集合,也可能只是原语。将这些字段添加到singleton中,例如:
double conversionRate, taxRate;
int securityNumber;
.... // and so on
现在,您需要一些单例的方法来更新这些数据。让我们称之为updateData()
。每当用户更改任何片段中的某些数据时,此片段应调用:
Singleton.getInstance().updateData(dataType, data);
作为参数,让我们放置数据类型和包含这些数据的某个对象
其次,每次更新时,您都需要更新其他演示文稿片段中的数据,对吗?因此,这个updateData()
方法应该在当前运行的片段列表中运行,并向每个片段发送新数据。如何实施非常简单,通过回调方法。为此,您需要:
1) 使用一种方法创建一种可更新的公共接口:public void onUpdate(int数据类型,数据数据)
2) 通过在类名后实现可更新的在每个片段上实现此接口
3) 在类主体中实现其唯一的方法onUpdate()
。在这个实现中,每个片段都会考虑,首先,它是否需要使用给定数据类型的数据,第二,处理这些接收的数据(例如改变其文本视图值):
第三,您的单身汉如何知道应该向谁发送更新的数据?非常简单:只需添加一个将所有片段作为可更新对象包含在其中的存储:
List<Updateable> listeners = new ArrayList<Updateable>;
现在,每个想要接收更新的片段(即实现可更新的接口)应该在创建后立即注册为侦听器并继续:
Singleton.getInstance().registerListener(this);
并在onDestroy
上注销,或者当它不再需要侦听更新时:
Singleton.getInstance().unregisterListener(this);
注意:为了防止内存泄漏,当您不再使用此对象时,应该注销侦听器。否则,对它的引用将保留在侦听器列表中,使垃圾收集器无法访问它
在我们创建了添加和删除侦听器的方法之后,让我们回到前面提到的singleton方法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(…)
——新数据将存储在Singleton中并自动广播到其他片段
==================================================================
免责声明:这不是Observer设计模式的精确实现,只是它的简化版本,以便初学者更清楚、更容易理解。这就是为什么我不使用诸如Observer
、notify
等常见名称的原因。这只是更深入理解常见设计模式的第一步的工作示例。非常感谢,这消除了我在实现此设计模式时遇到的大量困惑——在第一次学习时很难掌握。我不清楚的一件事是如何“告诉”宿主活动更改当前正在查看的片段。例如,当在和Updateable
fragment中接收到更新时,它如何将显示的片段需要替换的消息传递给宿主活动?这对于回调侦听器来说是直观的,但是如果有许多片段需要活动实现它们的回调侦听器呢?如果您有多个片段,每个片段都执行自己的任务,则不需要在活动中实现所提到的接口。Singleton对象将是绝对独立的,它将保留对侦听更新的片段的引用,并直接向这些片段广播更新。要使Singleton对象独立于活动生命周期,请在application object中保留对它的引用,无活动对象。如果您的活动应根据更新的数据操作片段,则还应通过onUpdate()
接收更新并进行此类操作。在经典的观察者模式中,更新是一种广播消息。每个接收者(观察者)都应该自己决定如何处理接收到的数据,或者如果它们不符合自己的兴趣,就忽略它们。
Singleton.getInstance().unregisterListener(this);
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) {}
}
}