Android观察者模式(Observable)实例

一:前言

最近在遇到了Android的开发中常用到的设计模式之观察者模式,观察者模式,所谓的模式就是一种设计思想,可以按照某种模式,写出更合理,简单,有效的代码。可以用在Android开发中,也可以用在Java,C#等等开发中,就类似单例模式,代理模式,模版等等。

二:什么是观察者模式
个人理解所谓的观察者模式,打个比喻,就好比,老师在教室上课,学生在教室听课,这里的老师就是被观察者,而这时候的在听课的学生就是观察者,老师通过说话,来传递知识,老师每说一个知识,学生都会实时做出相应的反映。这就是所谓的观察者模式,也有人理解为事件的订阅,再以事件的订阅打个比喻,假设现在有个Android授课老师在讲课,有想学习Android的学生想实时的学习到新的Android知识,那怎么办,没错那就是必须的关注这个老师,你才能实时的获取到最新的Android知识,这里的关注就是,关注的过程就是事件的订阅。(个人理解,有什么不的对的地方,欢迎指教)

三:举例说明
我们这里用实际的需求来说明下.
需求:现在有学生A(也就是Activity) 去回答老师提出的问题,最后有老师,告诉学生是否回答正确,如果回答正确的学生,开心的笑了,不正确学生表现很沮丧。(也就是跳转到B Activity,去回答问题,最后提交,服务器将答题结果发布,A Activity接收结果,根据结果做出一些操作)
四:具体代码实现

1.这里我们先定义一个被观察者,也就是老师类。

package com.zhang.zs.zhangtest;

import java.util.Observable;

/**
 * Created by zs on 2016/11/12.
 * 老师类,老师就是给自己的学生传播知识,让自己的学生收益。
 * 这里老师就好像是一个消息的发送者,可以认为,老师就是被观察者
 * 这里继承系统的Observable类
 * name_ok.由于在同一时间段,只能有一个老师给学生传递知识,所以我们要把老师类(被观察者,事件发送源)
 * 对象设计成单例模式
 */
public class Teacher extends Observable {
    private Teacher() {

    }

    private static Teacher teacher = null;

    public static Teacher getInstance() {
        if (teacher == null) {
            synchronized (Teacher.class) {
                if (teacher == null) {
                    teacher = new Teacher();
                }
            }

        }
        return teacher;

    }

    public void postMessage(String eventtype) {

        setChanged();
        notifyObservers(eventtype);

    }


}

这里Teacher类就是被观察者,设计成单例模式,就是为了让整个系统中只存在一个消息的发送者。

2.现在新建一个EventType类。这里定义了一些,老师具体发送了一些什么信息,

package com.zhang.zs.zhangtest;

/**
 * Created by zs on 2016/11/12.
 * 定义一些事件常量
 *
 */
public class EventType {

    public static final String RESPONSE_SUCESS="resposeok"; //回答正确
    public static final String RESPONSE_FAIL="responseno";  //回答错误
}

3.老师发送消息,学生怎能接受的到呢,到底是那个学生接受到呢,就好比我是哈佛校长(校长也是老师)发布的内部消息,当然只有,哈佛学校的学生才能接受消息把,这里是有关联的,如果你想接受哈佛的消息怎么办,想办法加入哈佛呗,这里的观察者也是一样的。首先将我们的A Activity 注册到 我们的消息的发送者中。让他知道有你这个学生。在一般开发中我们都会定义一个基类,这里我们也定义一个基类,(观察者多的话,一个一个添加多麻烦)。基类如下

package com.zhang.zs.zhangtest;

import android.app.Activity;
import android.os.Bundle;

import java.util.Observable;
import java.util.Observer;

/**
 * Created by zs on 2016/11/12.
 */
public  class BaseActivity extends Activity implements Observer{

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if(this instanceof Observer){
            //将要接收消息的学生添加
            Teacher.getInstance().addObserver(this);
        }

    }

    //接受到消息的回调方法,就是学生接受到消息后做出的反映
    @Override
    public void update(Observable observable, Object data) {

    }


}

4.这时候我们来定义一个学生,(A activity)
功能:一个按钮,一个显示图片的控件,点击按钮,转到B activity ,图片控件,显示根据老师公布学生答题的对错的结果去显示相应的图片,
布局文件:

<?xml version="1.0" encoding="utf-8"?>
<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:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="reply"
        android:text="我要回答问题" />

    <ImageView
        android:id="@+id/image"
        android:layout_width="80dp"
        android:layout_height="80dp"

        android:layout_centerInParent="true"
         />

</RelativeLayout>

Activity 代码;

package com.zhang.zs.zhangtest;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;

import java.util.Observable;

public class MainActivity extends BaseActivity {

    private ImageView image;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        image = (ImageView) findViewById(R.id.image);
    }


    public void reply(View v) {

        //跳转也去答题
        startActivity(new Intent(this, ReplayActivity.class));
    }

    /**
     * 根据接收到的消息去做相关的功能
     * @param observable
     * @param data
     */
    @Override
    public void update(Observable observable, Object data) {
        if (data instanceof String) {
            String message = (String) data;
//            接收到成功消息就显示成功的图片 ,失败就显示失败的图片
            if (EventType.RESPONSE_SUCESS.equals(message)) {
                image.setBackgroundResource(R.drawable.name_ok);

            } else if (EventType.RESPONSE_FAIL.equals(message)) {
                image.setBackgroundResource(R.drawable.name_err);
            }

        }


    }
}

5.这里定义答题activity,根据答题结果,老师(被观察者)发出相应的消息。

扫描二维码关注公众号,回复: 11168986 查看本文章

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical">

    <TextView

        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="题目一:1+1=?"
        android:textSize="19sp" />

    <RadioGroup
        android:id="@+id/anser"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:orientation="horizontal">

        <RadioButton
            android:id="@+id/two"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="2"
            android:textSize="19sp" />

        <RadioButton
            android:id="@+id/three"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="3"
            android:textSize="19sp" />

        <RadioButton
            android:id="@+id/four"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="4"
            android:textSize="19sp" />

        <RadioButton
            android:id="@+id/five"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="5"
            android:textSize="19sp" />
    </RadioGroup>

    <Button
        android:layout_marginTop="20dp"
        android:text="提交"
        android:onClick="response"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

想用activity代码:

package com.zhang.zs.zhangtest;

import android.os.Bundle;
import android.view.View;
import android.widget.RadioGroup;
import android.widget.Toast;

public class ReplayActivity extends BaseActivity {

    private RadioGroup anser;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_replay);

        anser = (RadioGroup) findViewById(R.id.anser);

    }


    //根据消息发送消息
    public void response(View view) {

        int checkId = anser.getCheckedRadioButtonId();
        if (checkId == R.id.two) {
//            老师发送答题成功的消息
            Teacher.getInstance().postMessage(EventType.RESPONSE_SUCESS);
        } else if (checkId == R.id.three || checkId == R.id.four || checkId == R.id.five) {
//            老师发送答题失败的消息
            Teacher.getInstance().postMessage(EventType.RESPONSE_FAIL);
        } else {
            Toast.makeText(this, "请回答这个问题", Toast.LENGTH_SHORT).show();
            return;
        }

        finish();

    }


}

项目源码地址:https://github.com/sdsjk/Observable

到现在,整个需求就做完了,在重复一下,点击mainActivity中的按钮去跳转到 Bactivity去答题,答完题,点击提交按钮,会根据你的答案发送出不同的消息,这时候,Mainactivity就会接受到消息,做出相应的处理。如图
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

原创文章 375 获赞 138 访问量 53万+

猜你喜欢

转载自blog.csdn.net/qq_27061049/article/details/105544731