观察者模式&在Android中的应用

观察者模式

介绍

1.概念

定义对象之间的一种一对多的依赖关系,使得每当一个对象状态发生改变时,其相对依赖对象皆得到通知并被自动更新。

2.使用场景

一个对象的改变导致一个或多个对象也发生改变

使用观察者模式原因

 有些场景需要频繁发送更新消息,如果使用广播的话,会有延迟的情况出现。

code

这里以我的音乐播放器的一个例子来说一下。

被观察者接口(目标类)

/**
* author : stoneWang
* date   : 2019/4/38:59
* 被观察者接口
*/
public interface MusicSubjectListener {

    void add(MusicObserverListener observerListener);

    void notifyObserver(int content);

    void remove(MusicObserverListener observerListener);

}

观察者接口

/**
* author : stoneWang
* date   : 2019/4/38:58
* 观察者接口
*/
public interface MusicObserverListener {

    void observerUpData(int content);//刷新操作

}

观察者管理类

import java.util.concurrent.CopyOnWriteArrayList;

/**
* author : stoneWang
* date   : 2019/4/39:01
* 观察者管理类
*/
public class MusicObserverManager implements MusicSubjectListener {
    private static String TAG = "MusicPositionObserverManager";
    private static MusicObserverManager observerManager = null;

    //观察者接口集合(使用CopyOnWriteArrayList而不是List是为了线程安全)
    private CopyOnWriteArrayList<MusicObserverListener> list = new CopyOnWriteArrayList<>();

    /**
     * 静态内部类单例
     * @return 观察者管理类的实例
     */
    public static MusicObserverManager getInstance() {
        return SingletonHolder.observerManager;
    }

    private static class SingletonHolder {
        private static final MusicObserverManager observerManager = new MusicObserverManager();
    }

    /**
     * 加入监听队列
     * @param observerListener
     */
    @Override
    public void add(MusicObserverListener observerListener) {
        list.add(observerListener);
    }

    /**
     * 通知观察者刷新数据
     * @param content
     */
    @Override
    public void notifyObserver(int content) {
        for (MusicObserverListener observerListener : list) {
            observerListener.observerUpData(content);
        }
    }

    /**
     * 监听队列中移除
     * @param observerListener
     */
    @Override
    public void remove(MusicObserverListener observerListener) {
        if (list.contains(observerListener)) {
            list.remove(observerListener);
        }
    }
}

在需要被通知的类,即观察者类中,继承观察者接口;

然后实现观察者接口中的observerUpData方法,在其中书写更新的逻辑;

同时需要在onCreate方法中将该观察者对象添加进观察者对象,在该Fragment/Activity销毁的时候,将该观察者移除。

public class LrcFragment extends Fragment implements MusicObserverListener {

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);


    //添加进观察者队列
    MusicObserverManager.getInstance().add(this);


}

/**
* MusicPosition观察者刷新数据类
* @param content
*/
@Override
public void observerUpData(int content) {
    switch (content) {
        case MediaStateCode.MUSIC_POSITION_CHANGED:
            //书写自己的逻辑
            DclTimerTask.getInstance().destroyed();
            init();
            break;


        case MediaStateCode.PLAY_START:
        case MediaStateCode.PLAY_CONTINUE:
            //书写自己的逻辑
            DclTimerTask.getInstance().start();
            break;


        case MediaStateCode.PLAY_STOP:
        case MediaStateCode.PLAY_PAUSE:
            //书写自己的逻辑
            DclTimerTask.getInstance().destroyed();
            break;


        default:
            Log.i(TAG, "observerUpData->观察者类数据已刷新");
            break;
    }
}

@Override
public void onDestroy() {
    super.onDestroy();

    //从观察者队列中移除
    MusicObserverManager.getInstance().remove(this);

}

}

在被观察者类中,

在需要发送消息的时候即状态发生改变时,触发观察者管理类的notifyObserver方法,通知观察者队列中的所有观察者更新数据

/*问题播放结束时没有监听,修改播放器的状态*/
public class MediaUtils {

//开始
public static void start() {
    if (getMediaPlayer() != null) {
        getMediaPlayer().start();
        MediaUtils.currentState = MediaStateCode.PLAY_START;
    }


    //被观察者发生变化->PLAY_START
    MusicObserverManager.getInstance().notifyObserver(MediaStateCode.PLAY_START);
}


//暂停
public static void pause() {
    if (getMediaPlayer() != null && getMediaPlayer().isPlaying()) {
        getMediaPlayer().pause();
        MediaUtils.currentState = MediaStateCode.PLAY_PAUSE;
    }


    //被观察者发生变化->PLAY_PAUSE
    MusicObserverManager.getInstance().notifyObserver(MediaStateCode.PLAY_PAUSE);
}

}

好啦,就是这样啦,具体的应用在我的GitHub上,如果有兴趣可以看看:

GitHub - stoneWangL/StoneMusic

不感兴趣就算啦,哈哈^_^

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值