Android觀察者模式實(shí)例分析
本文實(shí)例講述了Android觀察者模式。分享給大家供大家參考。具體分析如下:
一、環(huán)境:
主機(jī):WIN8
開發(fā)環(huán)境:Eclipse
二、說明:
1.打開sd卡中的xml文件,如果不存在,這新建一個,并寫入默認(rèn)配置
2.讀取xml文件
3.Config_Info.java為配置信息數(shù)據(jù)結(jié)構(gòu)
4.IF_Config.java為配置類的存取接口,其他類可以通過此接口直接獲取配置信息
5.IF_Subject_Config.java為觀察者模式目標(biāo)類接口
6.IF_Observer_Config.java為觀察者模式觀察者類接口
7.Config.java為配置類,完成1,2兩部工作,同時是觀察者模式的目標(biāo)類,一旦配置信息由變化著通知觀察者類
8.TestClass.java為觀察者模式的觀察者
通過存取接口+觀察者模式可以實(shí)現(xiàn)松耦合的設(shè)計。
三、xml文件格式:
<?xml version="1.0" encoding="UTF-8" standalone="true"?> -<config> <title>遠(yuǎn)程視頻會見系統(tǒng)</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:
/**
* 配置信息數(shù)據(jù)類型
* 新建時間:2014/12/8 by jdh
*/
package com.example.helloanychat;
public class Config_Info {
//標(biāo)題
public String title;
//本機(jī)ip
public String local_ip;
//本機(jī)端口
public int local_port;
//調(diào)度服務(wù)器ip
public String schedule_server_ip;
//調(diào)度服務(wù)器端口
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:
/**
* 接口:配置類,觀察者模式:目標(biāo)
* 新建時間: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;
/**
* 構(gòu)造函數(shù)
*/
public Config() {
//生成配置信息
generate_config_info();
//創(chuàng)建定時線程
Timer_Work.schedule(new Task(),INTERVAL_WORK,INTERVAL_WORK);
// 定時任務(wù)
}
//接口:讀寫
@Override
public Config_Info get_config_info() {
return Info;
}
//讀寫,觀察者模式:目標(biāo)
@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);
}
}
/**
* 得到本機(jī)ip地址
* @return 本機(jī)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數(shù)據(jù)流
* Config_Info的本機(jī)ip信息不會保存
* @param info:配置信息
* @return xml的String數(shù)據(jù)流
*/
private String produce_xml_string(Config_Info info) {
StringWriter stringWriter = new StringWriter();
try {
// 獲取XmlSerializer對象
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlSerializer xmlSerializer = factory.newSerializer();
// 設(shè)置輸出流對象
xmlSerializer.setOutput(stringWriter);
//開始標(biāo)簽
xmlSerializer.startDocument("utf-8", true);
xmlSerializer.startTag(null, "config");
//標(biāo)題
xmlSerializer.startTag(null, "title");
xmlSerializer.text(info.title);
xmlSerializer.endTag(null, "title");
//本機(jī)端口
xmlSerializer.startTag(null, "local_port");
xmlSerializer.text(Integer.toString(info.local_port));
xmlSerializer.endTag(null, "local_port");
//調(diào)度服務(wù)器ip
xmlSerializer.startTag(null, "schedule_service_ip");
xmlSerializer.text(info.schedule_server_ip);
xmlSerializer.endTag(null, "schedule_service_ip");
//調(diào)度服務(wù)器端口
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();
}
/**
* 工作任務(wù):得到配置信息
*/
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();
//得到本機(jī)ip地址
info.local_ip = getLocalIpAddress();
//獲取SD卡目錄
sd_path = Environment.getExternalStorageDirectory();
//判斷文件夾是否存在
file_cfg_dir = new File(sd_path.getPath() + "http://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("創(chuàng)建文件夾成功!");
} else {
System.out.println("創(chuàng)建文件夾失敗!");
}
}
//判斷配置文件是否存在
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("創(chuàng)建文件cfg.xml成功!");
//生成初始化的配置數(shù)據(jù)
try {
out = new FileOutputStream(file_cfg);
//保存默認(rèn)配置
Info.title = "遠(yuǎn)程視頻會見系統(tǒng)";
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();
//保存本機(jī)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);
// 獲取根節(jié)點(diǎn)
Element root = document.getDocumentElement();
NodeList node = root.getChildNodes();
//獲得第1子節(jié)點(diǎn):標(biāo)題
info.title = node.item(0).getFirstChild().getNodeValue();
//獲得第2子節(jié)點(diǎn):本機(jī)端口
info.local_port = Integer.parseInt(node.item(1).getFirstChild().getNodeValue());
//獲得第3子節(jié)點(diǎn):調(diào)度服務(wù)器ip
info.schedule_server_ip = node.item(2).getFirstChild().getNodeValue();
//獲得第4子節(jié)點(diǎn):調(diào)度服務(wù)器端口
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("-------------更新數(shù)據(jù):%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程序設(shè)計有所幫助。
相關(guān)文章
Android自定義實(shí)現(xiàn)BaseAdapter的普通實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了Android自定義實(shí)現(xiàn)BaseAdapter的普通實(shí)現(xiàn),感興趣的小伙伴們可以參考一下2016-08-08
搭建簡易藍(lán)牙定位系統(tǒng)的實(shí)現(xiàn)方法
下面小編就為大家?guī)硪黄罱ê喴姿{(lán)牙定位系統(tǒng)的實(shí)現(xiàn)方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-03-03
Android Studio做超好玩的拼圖游戲 附送詳細(xì)注釋源碼
這篇文章主要介紹了用Android Studio做的一個超好玩的拼圖游戲,你是0基礎(chǔ)Android小白也能包你學(xué)會,另外附送超詳細(xì)注釋的源碼,建議收藏!2021-08-08
Android RecyclerView仿新聞頭條的頻道管理功能
這篇文章主要介紹了Android RecyclerView仿新聞頭條的頻道管理功能,需要的朋友可以參考下2017-06-06
Android自定義控件單位尺寸實(shí)現(xiàn)代碼
這篇文章主要介紹了Android自定義控件單位尺寸實(shí)現(xiàn)代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-04-04
Android實(shí)現(xiàn)聯(lián)動下拉框二級地市聯(lián)動下拉框功能
這篇文章主要介紹了Android實(shí)現(xiàn)聯(lián)動下拉框二級地市聯(lián)動下拉框功能,本文給大家分享思路步驟,給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2018-12-12

