Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/388.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android发布/订阅单例_Java_Android_Android Layout_Android Fragments_Software Design - Fatal编程技术网

Java Android发布/订阅单例

Java Android发布/订阅单例,java,android,android-layout,android-fragments,software-design,Java,Android,Android Layout,Android Fragments,Software Design,有人能提供一个使用发布/订阅单例模式在片段之间传递信息的简单示例吗。上周,我询问了以下场景,并建议使用此方法;我似乎不能把我的头围绕着它 我有一个使用导航抽屉布局的应用程序,具有各种 执行独立功能的“子应用程序”(例如 计算器应用程序,与所得税无关的“子应用程序” 计算、公制/英制换算等)。一定要 计算器,我有一个数据输入/选择片段和一个数据 以某种有意义的方式显示计算的表示片段 方式的类型。因此,我在应用程序中的唯一活动是 MainActivity,握住导航抽屉和内容窗格。这个 问题是:设计应

有人能提供一个使用发布/订阅单例模式在片段之间传递信息的简单示例吗。上周,我询问了以下场景,并建议使用此方法;我似乎不能把我的头围绕着它

我有一个使用导航抽屉布局的应用程序,具有各种 执行独立功能的“子应用程序”(例如 计算器应用程序,与所得税无关的“子应用程序” 计算、公制/英制换算等)。一定要 计算器,我有一个数据输入/选择片段和一个数据 以某种有意义的方式显示计算的表示片段 方式的类型。因此,我在应用程序中的唯一活动是 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) {}
   } 
}