本文实例讲述了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文件格式:
1
2
3
4
5
6
7
|
<? 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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
/**
* 配置信息数据类型
* 新建时间: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:
1
2
3
4
5
6
7
8
|
/**
* 接口:配置类,读写
* 新建时间:2014/12/8 by jdh
*/
package com.example.helloanychat;
public interface IF_Config {
public Config_Info get_config_info();
}
|
IF_Subject_Config.java:
1
2
3
4
5
6
7
8
9
10
|
/**
* 接口:配置类,观察者模式:目标
* 新建时间: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:
1
2
3
4
5
6
7
8
|
/**
* 接口:配置类,观察者模式:观察者
* 新建时间:2014/12/8 by jdh
*/
package com.example.helloanychat;
public interface IF_Observer_Config {
public void update(Config_Info info);
}
|
Config.java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
|
/**
* 配置信息类
* 新建日期: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:
1
2
3
4
5
6
7
8
9
10
|
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:
1
2
3
4
|
TestClass testclass = new TestClass();
Config config = new Config();
mEditIP.setText(config.get_config_info().local_ip);
config.register_observer(testclass);
|
希望本文所述对大家的Android程序设计有所帮助。