一个类实现Android观察者模式(最简单实用的观察者模式)
来源:互联网 发布:日本产假多少天 知乎 编辑:程序博客网 时间:2024/05/22 04:27
本篇为大家介绍一下观察者模式。
这里不会再画那些无聊的关系图,类图。因为观察者模式非常简单,那些图网上到处都是,连百度百科都已经有很长的内容了。
简单的说一下逻辑:当某事件(Event)被任何地方触发的时候,这个事件的所有监听者(Listener),都会触发监听器。
当然,这个事件也可能没有一个监听者,但他并不关心这个。
先来看看公共处理逻辑类
package com.chenjian.observer;import android.content.Intent;import java.lang.ref.SoftReference;import java.util.ArrayList;import java.util.HashMap;import java.util.Map;/** * Created by ChenJian * 2016.8.3 16:48:48. */public class SystemEvent { private static Map<SystemEventConst, ArrayList<SoftReference<EventListener>>> mEventMap = new HashMap<>(); public static void release() { if (mEventMap != null) { for (Map.Entry<SystemEventConst, ArrayList<SoftReference<EventListener>>> entry : mEventMap.entrySet()) { if (entry.getValue() != null) { entry.getValue().clear(); } } mEventMap.clear(); mEventMap = null; } } public interface EventListener { void onEvent(SystemEventConst eventType, Intent data); } public synchronized static boolean addListener(SystemEventConst eventType, EventListener eventListener) { if (mEventMap == null) { return false; } ArrayList<SoftReference<EventListener>> list = mEventMap.get(eventType); if (list == null) { list = new ArrayList<>(); } for (SoftReference<EventListener> softListener : list) { if (softListener != null) { EventListener sEventListener = softListener.get(); if (sEventListener != null && sEventListener == eventListener) { return false; } } } SoftReference<EventListener> listener = new SoftReference<>(eventListener); list.add(listener); mEventMap.put(eventType, list); return true; } public synchronized static void removeListener(SystemEventConst eventType, EventListener listener) { ArrayList<SoftReference<EventListener>> list = mEventMap.get(eventType); if (null == list) { return; } for (int i = 0; i < list.size(); i++) { EventListener l = list.get(i).get(); if (l == listener) { list.remove(i); break; } } } public synchronized static void removeListener(SystemEventConst eventType) { mEventMap.remove(eventType); } public synchronized static void fireEvent(SystemEventConst eventType, Intent data) { ArrayList<SoftReference<EventListener>> list = mEventMap.get(eventType); if (list != null) { for (int i = 0; i < list.size(); i++) { EventListener listener = list.get(i).get(); if (listener != null) { listener.onEvent(eventType, data); } } } } public synchronized static void fireEvent(SystemEventConst eventType) { fireEvent(eventType, null); }}这个类中,保存着一个map,key为事件类型,value是这个事件所对应的监听器列表。
本类中也包含了一些添加删除监听器的方法,同样也有触发事件的方法。
触发事件时,可以不带参数,带参数的话,这里选择的是Intent类型,我不用Map而用Intent,因为个人感觉Intent更符合Android的数据传递思想。
再来看看事件类型,SystemEventConst类
package com.chenjian.observer;/** * Created by ChenJian * 2016.8.3 16:48:48. */public enum SystemEventConst { /** * 总金额变化 */ EVENT_TOTAL_MONEY_CHANGE,}
是一个枚举类型,里面可以定义自己想要的事件。
再来看看使用
主界面布局
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin"> <TextView android:id="@+id/tv_main_money" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/money" /> <Button android:id="@+id/btn_main" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="30dp" android:text="@string/button" /></LinearLayout>
代码
package com.chenjian.observer;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.TextView;public class MainActivity extends Activity implements SystemEvent.EventListener { private TextView mMoneyTextView; private Button mButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findView(); setListener(); } @Override protected void onDestroy() { super.onDestroy(); SystemEvent.removeListener(SystemEventConst.EVENT_TOTAL_MONEY_CHANGE, this); } private void findView() { mMoneyTextView = (TextView) findViewById(R.id.tv_main_money); mButton = (Button) findViewById(R.id.btn_main); } private void setListener() { mButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(MainActivity.this, OtherActivity.class)); } }); SystemEvent.addListener(SystemEventConst.EVENT_TOTAL_MONEY_CHANGE, this); } @Override public void onEvent(SystemEventConst eventType, Intent data) { switch (eventType) { case EVENT_TOTAL_MONEY_CHANGE: mMoneyTextView.setText(data.getAction()); break; } }}
TextView上显示金额,按钮点击后跳转到另一个界面。
这里使用到了观察者模式,在一开始的时候,注册了监听器,在事件发生的时候,改变金额的值。
要非常注意的是:在监听者被销毁不再使用的时候,要把自己从监听器列表中删除掉
再来看看OtherActivity
package com.chenjian.observer;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.os.Handler;/** * 作者: ChenJian * 时间: 2016.12.28 10:42 */public class OtherActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Intent intent = new Intent("$110"); SystemEvent.fireEvent(SystemEventConst.EVENT_TOTAL_MONEY_CHANGE, intent); new Handler().postDelayed(new Runnable() { @Override public void run() { finish(); } }, 3000); }}
触发事件,并带上金额的参数,三秒后退出。
看看前后界面显示
Android中观察者模式还是相对常用的,比如本例,在主界面或者其它页面都可能显示着用户的个人信息,金额昵称之类的,在详情页或者修改页去做修改后,通知相关页面做出修改。如果使用BrocastReceiver或者全局变量,就显得非常的麻烦。
源码下载点击打开链接
1 0
- 一个类实现Android观察者模式(最简单实用的观察者模式)
- 最简单的观察者模式实现
- 一个简单观察者模式的实现 cocos2dx
- Android观察者模式简单实现
- Android观察者模式的简单实现demo
- Android观察者模式的简单实现demo
- 观察者模式的简单实现
- 简单实现的观察者模式
- 观察者模式(简单的实现)
- 观察者模式简单实现
- 最简单的观察者模式纯JAVA实现
- 最常用的设计模式---观察者模式(C++实现)
- 最常用的设计模式---观察者模式(C++实现)
- 最简单的观察者模式--转载
- 观察者模式--一个简单的模拟
- 一个简单的观察者模式例子
- 观察者模式java的简单实现
- RCTDeviceEventEmitter 实现简单的观察者模式
- 一台电脑同时运行多个tomcat配置方法
- 今天开始,将记录成长,点滴耕耘与您一同分享!
- 浏览器同源政策及其规避方法:同源策略从根本上是浏览器对web应用在安全方面的一种控制方法
- mysql死锁问题分析
- 小谈chrome调试命令:console.log的使用
- 一个类实现Android观察者模式(最简单实用的观察者模式)
- 查看mysql 32位64位
- hiredis的各种windows版本
- 如何查看 SQL Server 占用内存
- javaEE:day3-servlet生命周期、提交解决中文乱码、tomcat加载jar包或类文件的顺序
- 常用正则表达式大全
- Maven中央存储库
- [Mapbox GL]调整LineString使其适应地图边界
- sql 同一列的多行内容拼接成字符串