Android观察者模式实例分析
作者:jdh99 发布时间:2022-07-24 09:21:32
标签:Android,观察者,模式
本文实例讲述了Android观察者模式。分享给大家供大家参考。具体分析如下:
一、环境:
主机:WIN8
开发环境:Eclipse
二、说明:
1.打开sd卡中的xml文件,如果不存在,这新建一个,并写入默认配置
2.读取xml文件
3.Config_Info.java为配置信息数据结构
4.IF_Config.java为配置类的存取接口,其他类可以通过此接口直接获取配置信息
5.IF_Subject_Config.java为观察者模式目标类接口
6.IF_Observer_Config.java为观察者模式观察者类接口
7.Config.java为配置类,完成1,2两部工作,同时是观察者模式的目标类,一旦配置信息由变化着通知观察者类
8.TestClass.java为观察者模式的观察者
通过存取接口+观察者模式可以实现松耦合的设计。
三、xml文件格式:
<?xml version="1.0" encoding="UTF-8" standalone="true"?>
-<config>
<title>远程视频会见系统</title>
<local_port>12600</local_port>
<schedule_service_ip>10.58.1.59</schedule_service_ip>
<schedule_service_port>12601</schedule_service_port>
</config>
四、源代码:
Config_Info.java:
/**
* 配置信息数据类型
* 新建时间:2014/12/8 by jdh
*/
package com.example.helloanychat;
public class Config_Info {
//标题
public String title;
//本机ip
public String local_ip;
//本机端口
public int local_port;
//调度服务器ip
public String schedule_server_ip;
//调度服务器端口
public int schedule_server_port;
}
IF_Config.java:
/**
* 接口:配置类,读写
* 新建时间:2014/12/8 by jdh
*/
package com.example.helloanychat;
public interface IF_Config {
public Config_Info get_config_info();
}
IF_Subject_Config.java:
/**
* 接口:配置类,观察者模式:目标
* 新建时间:2014/12/8 by jdh
*/
package com.example.helloanychat;
public interface IF_Subject_Config {
public void register_observer(IF_Observer_Config observer);
public void remove_observer(IF_Observer_Config observer);
public void notify_observer();
}
IF_Observer_Config.java:
/**
* 接口:配置类,观察者模式:观察者
* 新建时间:2014/12/8 by jdh
*/
package com.example.helloanychat;
public interface IF_Observer_Config {
public void update(Config_Info info);
}
Config.java:
/**
* 配置信息类
* 新建日期:2014/12/8 by jdh
* 修改日期:2014/12/9 by jdh
*/
package com.example.helloanychat;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import android.os.Environment;
import android.util.Log;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xmlpull.v1.XmlPullParserFactory;
import org.xmlpull.v1.XmlSerializer;
public class Config implements IF_Config,IF_Subject_Config {
//配置信息
private Config_Info Info = new Config_Info();
//存储观察者的列表
private List<IF_Observer_Config> Observers = new ArrayList<IF_Observer_Config>();
//定时器
private Timer Timer_Work = new Timer();
//工作间隔,单位:ms
private final int INTERVAL_WORK = 5000;
/**
* 构造函数
*/
public Config() {
//生成配置信息
generate_config_info();
//创建定时线程
Timer_Work.schedule(new Task(),INTERVAL_WORK,INTERVAL_WORK);
// 定时任务
}
//接口:读写
@Override
public Config_Info get_config_info() {
return Info;
}
//读写,观察者模式:目标
@Override
public void register_observer(IF_Observer_Config observer) {
Observers.add(observer);
}
@Override
public void remove_observer(IF_Observer_Config observer) {
int index = Observers.indexOf(observer);
if (index >= 0) {
Observers.remove(observer);
}
}
@Override
public void notify_observer() {
for (int i = 0; i < Observers.size(); i++) {
IF_Observer_Config o = (IF_Observer_Config) Observers.get(i);
o.update(Info);
}
}
/**
* 得到本机ip地址
* @return 本机ip地址
*/
private String getLocalIpAddress() {
try {
for (Enumeration<NetworkInterface> en = NetworkInterface
.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf
.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
//if (!inetAddress.isLoopbackAddress()) {
if (!inetAddress.isLoopbackAddress() && !(inetAddress instanceof Inet6Address)) {
return inetAddress.getHostAddress().toString();
}
}
}
} catch (SocketException ex) {
Log.e("WifiPreference IpAddress", ex.toString());
}
return null;
}
/**
* 生成xml配置文件的String数据流
* Config_Info的本机ip信息不会保存
* @param info:配置信息
* @return xml的String数据流
*/
private String produce_xml_string(Config_Info info) {
StringWriter stringWriter = new StringWriter();
try {
// 获取XmlSerializer对象
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlSerializer xmlSerializer = factory.newSerializer();
// 设置输出流对象
xmlSerializer.setOutput(stringWriter);
//开始标签
xmlSerializer.startDocument("utf-8", true);
xmlSerializer.startTag(null, "config");
//标题
xmlSerializer.startTag(null, "title");
xmlSerializer.text(info.title);
xmlSerializer.endTag(null, "title");
//本机端口
xmlSerializer.startTag(null, "local_port");
xmlSerializer.text(Integer.toString(info.local_port));
xmlSerializer.endTag(null, "local_port");
//调度服务器ip
xmlSerializer.startTag(null, "schedule_service_ip");
xmlSerializer.text(info.schedule_server_ip);
xmlSerializer.endTag(null, "schedule_service_ip");
//调度服务器端口
xmlSerializer.startTag(null, "schedule_service_port");
xmlSerializer.text(Integer.toString(info.schedule_server_port));
xmlSerializer.endTag(null, "schedule_service_port");
xmlSerializer.endTag(null, "config");
xmlSerializer.endDocument();
} catch (Exception e) {
e.printStackTrace();
}
return stringWriter.toString();
}
/**
* 工作任务:得到配置信息
*/
private void generate_config_info()
{
boolean ok;
File sd_path;
File file_cfg_dir;
File file_cfg;
FileOutputStream out;
String str;
FileInputStream in;
Config_Info info = new Config_Info();
//得到本机ip地址
info.local_ip = getLocalIpAddress();
//获取SD卡目录
sd_path = Environment.getExternalStorageDirectory();
//判断文件夹是否存在
file_cfg_dir = new File(sd_path.getPath() + "//Remote_Meeting");
if (!file_cfg_dir.exists() && !file_cfg_dir.isDirectory()) {
System.out.println("配置文件夹Remote_Meeting不存在!");
ok = file_cfg_dir.mkdirs();
if (ok) {
System.out.println("创建文件夹成功!");
} else {
System.out.println("创建文件夹失败!");
}
}
//判断配置文件是否存在
file_cfg = new File(file_cfg_dir.getPath(),"cfg.xml");
if (!file_cfg.exists())
{
System.out.println("配置文件cfg.xml不存在!");
try {
file_cfg.createNewFile();
System.out.println("创建文件cfg.xml成功!");
//生成初始化的配置数据
try {
out = new FileOutputStream(file_cfg);
//保存默认配置
Info.title = "远程视频会见系统";
Info.local_port = 12600;
Info.schedule_server_ip = "10.58.1.59";
Info.schedule_server_port = 12601;
str = produce_xml_string(Info);
out.write(str.getBytes());
out.close();
//保存本机ip
Info.local_ip = info.local_ip;
//通知观察者
notify_observer();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else
{
//解析xml文件
try {
in = new FileInputStream(file_cfg);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(in);
// 获取根节点
Element root = document.getDocumentElement();
NodeList node = root.getChildNodes();
//获得第1子节点:标题
info.title = node.item(0).getFirstChild().getNodeValue();
//获得第2子节点:本机端口
info.local_port = Integer.parseInt(node.item(1).getFirstChild().getNodeValue());
//获得第3子节点:调度服务器ip
info.schedule_server_ip = node.item(2).getFirstChild().getNodeValue();
//获得第4子节点:调度服务器端口
info.schedule_server_port = Integer.parseInt(node.item(3).getFirstChild().getNodeValue());
//判断配置信息是否变更
do
{
if (!info.title.equals(Info.title))
{
break;
}
if (!info.local_ip.equals(Info.local_ip))
{
break;
}
if (info.local_port != Info.local_port)
{
break;
}
if (!info.schedule_server_ip.equals(Info.schedule_server_ip))
{
break;
}
if (info.schedule_server_port != Info.schedule_server_port)
{
break;
}
//全部相同
return;
} while (false);
//赋值
Info.title = info.title;
Info.local_ip = info.local_ip;
Info.local_port = info.local_port;
Info.schedule_server_ip = info.schedule_server_ip;
Info.schedule_server_port = info.schedule_server_port;
//通知观察者
notify_observer();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 定时器线程定时工作
*/
private class Task extends TimerTask {
@Override
public void run() {
generate_config_info();
}
}
}
TestClass.java:
package com.example.helloanychat;
public class TestClass implements IF_Observer_Config {
public TestClass () {
}
@Override
public void update(Config_Info info) {
System.out.printf("-------------更新数据:%s,%s,%d,%s,%d\n",
info.title,info.local_ip,info.local_port,info.schedule_server_ip,info.schedule_server_port);
}
}
MainActivity:
TestClass testclass = new TestClass();
Config config = new Config();
mEditIP.setText(config.get_config_info().local_ip);
config.register_observer(testclass);
希望本文所述对大家的Android程序设计有所帮助。


猜你喜欢
- 一、概述项目中经常用到倒计时的功能,比如说限时抢购,手机获取验证码等等。而google官方也帮我们封装好了一个类:CountDownTime
- 问题描述在开发批量删除功能时,往往都是多条数据,所以前台需要传一个数组给后台,但是怎么在URL中绑定一个数组,同时在后台用@PathVari
- 这篇文章主要介绍了Spring AOP AspectJ使用及配置过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考
- 前言数字时间戳技术是数字签名技术一种变种的应用。是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08
- Annotation(注解)是JDK1.5及以后版本引入的。它可以用于创建文档,跟踪代码中的依赖性,甚至执行基本编译时检查。注解是以&
- 对象内存分配与回收策略对象的内存分配,往大方向讲,就是在堆上分配〔但也可能经过JIT编译后被拆散为标量类型并间接地栈上分配),对象主要分配在
- 具体效果如下图所示:方法一方法二产生这种问题的原因是因为moudles.xml中没有找到对应的moudle。加入对应的moudle即可,修改
- 顺序结构我们之前写的大多代码都是顺序结构的,即按照代码的顺序一行一行的执行代码1 System.out.println("you&
- 前言Spring中的Profile功能其实早在Spring 3.1的版本就已经出来,它可以理解为我们在Spring容器中所定义的Bean的逻
- 本文实例讲述了Java Swing实现窗体添加背景图片的2种方法。分享给大家供大家参考,具体如下:在美化程序时,常常需要在窗体上添加背景图片
- 作为Android应用开发者,不得不面对一个尴尬的局面,就是自己辛辛苦苦开发的应用可以被别人很轻易的就反编译出来。Google似乎也发现了这
- spring Session 提供了一套用于管理用户 session 信息的API和实现。Spring Session为企业级Java应用的
- 今天因为发布swagger-spring-boot-starter做一个问题的修复,然后碰到了下面这个问题,记录一下解决过程,帮助后续碰到类
- Spring开启注解AOP的支持放置的位置放在springmvc的aop,需要在springmvc的配置文件中写开启aop,而不是sprin
- 本文实例为大家分享了java实现马踏棋盘的具体代码,供大家参考,具体内容如下马踏棋盘算法介绍8X8棋盘,马走日字,要求每个方格只进入一次,走
- 获取sdcard目录 public static String getSDPath() { File sdDir
- 本文实例讲述了C#使用linq对数组进行筛选排序的方法。分享给大家供大家参考。具体如下:using System;using System.
- 废话不多说了,直接给大家贴代码了,具体代码如下所述:/*** 把一个View的对象转换成bitmap*/private Bitmap get
- Servlet 3.0之前的版本中,文件上传是个挺让人头疼的问题,虽然有第三方框架来实现,但使用也还是比较麻烦,在Servlet 3.0中,
- 前言基于安卓平台的连续滚动图像组件ContinuousScrollableImageView(https://github.com/Cutt