26设计模式之观察者模式


观察者模式是一种使用非常多,也非常有用的一种设计模式。该模式有2种对象,一种是被观察者,一种是观察者。被观察者是唯一的,观察者可以有多个,是一种一对多的关系。举个例子,好比我们去追一部正在更新的电视剧,这部电视剧就是我们被观察者而追电视剧的人就是观察者,如何在电视剧更新的时候追电视剧的人第一时间知道就是观察者模式需要解决的这类问题。在安卓中使用观察中是非常简单的,因为这两种对象Google已经帮我们分装好类了,我们只需要直接用就可以了,下面是分装好的两个类及常用的方法。

Observer(观察者),是一个接口类,只需要重写update方法就可以了,该方法在被观察者通知观察者数据改变时调用。

Observerable(被观察者),是一个类,常用的方法如下:

setChanged():数据改变时调用。

addObserver():添加观察者时调用。

下面我们就来使用者两个类演示一个示例,示例的效果是这样的,我们用观察者去观察一个图片下载的过程,如果图片下载完成就通知观察者去更新imageview上面的图片。

首先新建一个类继承Observerable类,里面代码如下:

public class MyObserverable extends Observable {
	// 数据改变时调用
	@Override
	protected void setChanged() {
		super.setChanged();
		Log.e("", "数据改变了!");
	}

	// 添加观察者时调用
	@Override
	public void addObserver(Observer observer) {
		super.addObserver(observer);
		Log.e("", "新增加了一个观察者!");
	}

	
}
MainActivity类实现Observer接口,重写update方法, update里的代码如下:

	@Override
	public void update(Observable observable, Object data) {
		// 将下载的图片显示到ImageView上面
		imgv.post(new Runnable() {
			@Override
			public void run() {
				imgv.setImageBitmap(bm);
			}
		});
	}

Activity布局文件如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <Button
        android:id="@+id/btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="下载图片" />

    <ImageView
        android:id="@+id/imgv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/btn"
        android:scaleType="centerInside"
        android:src="@drawable/ic_launcher" />

</RelativeLayout>

给按钮添加一个监听事件代码如下:

	// 下载图片
		btn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				new Thread(new Runnable() {
					@Override
					public void run() {
						try {
							HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
							conn.setReadTimeout(5 * 1000);
							conn.setConnectTimeout(5 * 1000);
							// 将输入流转换为图片
							bm = BitmapFactory.decodeStream(conn.getInputStream());

						} catch (MalformedURLException e) {
							e.printStackTrace();
						} catch (IOException e) {
							e.printStackTrace();
						}

						// 设置数据改变
						observerable.setChanged();
						// 通知观察者
						observerable.notifyObservers();
					}
				}).start();

			}
		});

点击按钮去下载一张图片,记得添加网络访问权限, 在oncreate方法里面我们做如下工作:

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		// 实例化observerable对象
		observerable = new MyObserverable();
		// 将自己添加到观察队列中
		observerable.addObserver(this);
		init();
	}
完整的MainActivity代码如下:

public class MainActivity extends Activity implements Observer {
	private ImageView imgv;
	private Button btn;
	private MyObserverable observerable;
	private Bitmap bm;
	private String url = "http://cdn.duitang.com/uploads/item/201409/05/20140905015324_zvwG2.png";

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		// 实例化observerable对象
		observerable = new MyObserverable();
		// 将自己添加到观察队列中
		observerable.addObserver(this);
		init();
	}

	private void init() {
		imgv = (ImageView) findViewById(R.id.imgv);
		btn = (Button) findViewById(R.id.btn);
		// 下载图片
		btn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				new Thread(new Runnable() {
					@Override
					public void run() {
						try {
							HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
							conn.setReadTimeout(5 * 1000);
							conn.setConnectTimeout(5 * 1000);
							// 将输入流转换为图片
							bm = BitmapFactory.decodeStream(conn.getInputStream());

						} catch (MalformedURLException e) {
							e.printStackTrace();
						} catch (IOException e) {
							e.printStackTrace();
						}

						// 设置数据改变
						observerable.setChanged();
						// 通知观察者
						observerable.notifyObservers();
					}
				}).start();

			}
		});
	}

	@Override
	public void update(Observable observable, Object data) {
		// 将下载的图片显示到ImageView上面
		imgv.post(new Runnable() {
			@Override
			public void run() {
				imgv.setImageBitmap(bm);
			}
		});
	}

}

MainActivity类实现观察者接口,将自己添加到观察队列中,点击按钮下载图片,下载完成使用被观察者通知观察者更新UI, 下面来看运行效果:

输出的Log:


扫描关注我的微信公众号:



最后有一个注意的问题,update方法并不是运行在主线程中而是在notifyObservers调用的线程中运行。附上下载demo:demo


  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值