您的位置:首页 > 其它

大文件 and 多下载任务的封装(二)--观察者模式--实现下载进度的实时更新

2016-11-13 07:16 573 查看

Observer

大文件 and 多下载任务的封装一

原文地址

大文件 and 多下载任务的封装三

上篇博客的内容讲述了ThreadPool的封装,这篇博客虽然是紧跟着上一篇的,但是本文的知识点是一个单独存在的,也就是观察者设计模式的使用。首先我们一起来分析一下,对于一个多任务大文件的下载过程为什么要使用到观察者模式呢?那么我们先来分析一下下的的需求,

一.下载任务的显示需求

1.很显然,当用户需要下载一个软件,或者音乐视频文件的时候,用户最想知道的莫过于就是下载进度了,根据我们平时使用的应用商店为例,当一个应用在下载的过程中,会在不同的界面显示进度,也就是不同的区域,同步的更新下载进度。

2.在这里我们可能会想到一个知识点,那就是回调接口也就是下面这个实例


//1.首先定义一个接口类
interface OnUpdateListener{
public void update(Integer progress);
}

//2.为回调借口增加初始化操作、
public void setOnUpdateListener(OnUpdateListener onUpdateListener){
this.onUpdateListener = onUpdateListener;
}

//3.在下载类中更新数据
if(onUpdateListener != null){
//更新下载进度
onUpdateListener.update(progress);
}

//4.这样就已经创建了一个回调借接口,接下来就是直接注册调用即可
XXX.setOnUpdateListener(new OnUpdateListener{
@Override
public void update(Integer progress){
//5.就可以在这里使用下载进度了
}
});


二.Observer的实现

相信大家已经对回调接口有了一定的了解,也已经明白了使用回调接口对单个下载任务更新进度是非常方便的,只需要完成以下几步,

创建回调接口

给回调借口实现set方法,用来动态的进行注册

调用回调接口函数,对进度实行实时更新

实例化一个回调借口,

使用调用set方法,初始化接口,便可以使用

单个下载任务的进度更新我们可以使用回调接口,那么多个下载任务呢?是不是也可以使用?现在我们来模仿一下上述几个步骤,尝试一下对下载任务的进度更新

一.第一步,创建一个回调接口,

public interface DownLoadObserver{
//1.下载进度发生改变
void DownLoadProgressChange(Integer progress);
}


二.第二步,

首先这是一个多任务的下载操作,所以不可能只有一个回调,所以这里我们肯定会想到用集合的方式,存储DownLoadObserver接口。

private static ArrayList<DownLoadObserver> observers = new ArrayList<DownLoadObserver>();


三.第三步

我们有了回调接口的集合,根据上面回调接口的步骤,我们还有需要动态的添加和删除操作,也就是所谓的注册接口,和取消注册(注销),

//注册
public void registerObserver(DownLoadObserver observer){
if(observer != null&& !observers.contains(observer)){
//1.注册,也就是将接口存入集合当中
observers.add(observer);
}
}

//注销
public void unRegisterObser(DownLoadObserver observer){
if(observer!= null&& observers.contains(observer)){
//2.注销,也就是从集合中删除
observers.remove(observer);
}
}


四.第四步

到现在为止呢,我们已经把接口的初始化,注册与注销完成了,那么现在我们要做的就是调用接口的方法,对下载进度进行实时的更新操作,因为是一个集合,所以我们需要循环遍历:

//提醒观察者,数据更新了
public void notifytyDownLoadPregress(Integer progress){
for (DownLoadObserver observer:observers) {
observer.DownLoadProgressChange(progress);
}
}


五.第五步

回调接口已经初始化完毕,基本功能都已经有了,下面呢我们尝试着去像使用单个回调接口一样去使用它

//1.实例化进度更新接口
DownLoadObserver load = new DownLoadObserver(){
//省略n行代码
}
//2.然后注册一下
XXX.registerObserver(load);

//3.当我们不想使用他的时候,我们可以对他进行注销操作
XXX.unregisterObserver(load);


六.第六步

到现在想必不用我说你们也应该知道,我们已经完成了对多任务下载过程的进度的更新操作,

??什么??你可能会这样疑问,说好的不是用观察者模式吗??你是不是在骗我们啊?

我可以肯定的回答,这就是观察者模式,其实观察者模式并没有我们想像的那么复杂,其实也就是一些回调接口而已。

三.我们现在来总结一下

首先我们新建一个回调接口类

使用一个集合,他的存储对象为接口类

实现三个方法,注册。注销,和实时更新操作(别忘记更新操作是对接口集合的便利操作)

接下来就可以使用了

四.代码

package com.example.orchid.googleplatstore.manager;

import java.util.ArrayList;

/**
* Created by orchid
* on 16-11-4.
*/

public class DownLoadManager {
//单例模式,饿汉模式
private static DownLoadManager mDM = new DownLoadManager();
//观察者,也就是回调接口的集合
private static ArrayList<DownLoadObserver> observers = new ArrayList<DownLoadObserver>();

//单例模式,饿汉模式
public static DownLoadManager getInstance(){
return mDM;
}

//注册观察者
public void registerObserver(DownLoadObserver observer){
if(observer != null&& !observers.contains(observer)){
observers.add(observer);
}
}

//注销观察者
public void unRegisterObser(DownLoadObserver observer){
if(observer!= null&& observers.contains(observer)){
observers.remove(observer);
}
}

//提醒观察者,刷新数据,下载的状态
public void notifyDownLoadStateChange(DownLoadInfo info){
for (DownLoadObserver observer:observers) {
observer.DOwnLoadStateChange(info);
}
}

//提醒观察者,数据更新了
public void notifytyDownLoadPregress(DownLoadInfo info){
for (DownLoadObserver observer:observers) {
observer.DownLoadProgressChange(info);
}
}

//观察者模式--回调接口
public interface DownLoadObserver{
//下载进度发生改变
void DownLoadProgressChange(DownLoadInfo info);
}
}


五.Thanks you

感谢大家的观看,有不足的地方还请大家指正,有不对的地方,还请提出以遍大家一起学习,
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐