(1)动态解析XML文件到expandablelist控件中,记住不是写死的
(这里面有解析两次XML来分别生成父节点和子节点的数据)
(2)巧用好handle机制可以使客户端跟服务端交互更容易
(3)(难点)类似于遥控器原理:通过socket来将服务器中的数据拉到本地中,然后发指令给服务端。而不是httpclient形式获取(这里面还涉及到从搭建客户端socket到,与模拟的服务器之间通讯之间的种种问题)
如果你觉得前面两点你可以轻松的应对,那么第三点就并不是那么容易了,也是这个项目中的核心部分代码。感谢有这个过程,让我们三个团队对代码有了深刻的理解。这个点我会做多一点的介绍。
一 动态解析XML文件到expandablelist控件中
这个功能类似于QQ中的好友列表,列表中的数据是从服务器解析的数据填充上去的。
自学的过程中一般都是填充一级菜单或者是直接利用数组直接写死好数据,这个阶段遇到的最大的问题就是如何填充多级的菜单里面的数据。
思路:解析两次的XML
技术:pull解析
xml测试文档
<?xml version="1.0" encoding="utf-8"?>
<facilitys>
<facilityType type="照明管理">
<facility>
<id>100</id>
<name>展柜灯光</name>
<state>1</state>
</facility>
<facility>
<id>101</id>
<name>厨房灯光</name>
<state>0</state>
</facility>
<facility>
<id>102</id>
<name>走廊灯光</name>
<state>1</state>
</facility>
<facility>
<id>103</id>
<name>客厅灯光</name>
<state>1</state>
</facility>
<facility>
<id>105</id>
<name>卧室灯光</name>
<state>1</state>
</facility>
<facility>
<id>106</id>
<name>展厅灯光</name>
<state>1</state>
</facility>
<facility>
<id>100</id>
<name>书房灯光</name>
<state>1</state>
</facility>
</facilityType>
<facilityType type="电器控制">
<facility>
<id>200</id>
<name>抽油烟机</name>
<state>1</state>
</facility>
<facility>
<id>201</id>
<name>电视移门</name>
<state>0</state>
</facility>
<facility>
<id>202</id>
<name>客厅空调</name>
<state>1</state>
</facility>
<facility>
<id>203</id>
<name>卧室电视</name>
<state>1</state>
</facility>
<facility>
<id>204</id>
<name>展厅空调</name>
<state>1</state>
</facility>
</facilityType>
<facilityType type="安全保护">
<facility>
<id>300</id>
<name>声光报警器</name>
<state>1</state>
</facility>
<facility>
<id>301</id>
<name>厨房红外报警</name>
<state>0</state>
</facility>
<facility>
<id>302</id>
<name>入户门门磁</name>
<state>1</state>
</facility>
<facility>
<id>303</id>
<name>可燃气阀门</name>
<state>1</state>
</facility>
<facility>
<id>304</id>
<name>厨房烟雾感应器</name>
<state>1</state>
</facility>
</facilityType>
</facilitys>
请看相关的代码:
package com.zknu.xmlpull;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.xmlpull.v1.XmlPullParser;
import com.zknu.entity.Facility;
import android.content.Context;
import android.util.Xml;
/**
* 作用:解析XML文档
*
* */
public class XmlPull {
/**
* 得到父元素
*
*
* */
static List<String> parents = null;
static String parent = null;
public static List<String> getParents(Context context, InputStream is)
throws Exception {
XmlPullParser parser = Xml.newPullParser();
parser.setInput(is, "utf-8");
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
parents = new ArrayList<String>();
break;
case XmlPullParser.START_TAG:
String name = parser.getName();
if (name.equals("facilityType")) {
parent = parser.getAttributeValue(0);
}
break;
case XmlPullParser.TEXT:
break;
case XmlPullParser.END_TAG:
if (parent != null) {
parents.add(parent);
}
parent = null;
break;
default:
break;
}
eventType = parser.next();
}
return parents;
}
/**
* 得到子元素
*
*
*
* */
public static List<List<Facility>> getChildren(Context context, InputStream is)
throws Exception {
List<List<Facility>> children = new ArrayList<List<Facility>>();
List<Facility> child = null;
Facility facility = null;
XmlPullParser parser = Xml.newPullParser();
parser.setInput(is, "utf-8");
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
child = new ArrayList<Facility>();
break;
case XmlPullParser.START_TAG:
String name = parser.getName();
if (name.equals("facilityType")) {
child = new ArrayList<Facility>();
}
if (name.equals("facility")) {
facility = new Facility();
} else if (name.equals("id")) {
facility.setId(Integer.parseInt(parser.nextText()));
} else if (name.equals("name")) {
facility.setName(parser.nextText());
} else if (name.equals("state")) {
facility.setState(Integer.parseInt(parser.nextText()));
}
break;
case XmlPullParser.TEXT:
break;
case XmlPullParser.END_TAG:
String endname = parser.getName();
if (endname.equals("facility")) {
child.add(facility);
facility = null;
}
if (endname.equals("facilityType")) {
children.add(child);
child = null;
}
break;
default:
break;
}
eventType = parser.next();
}
return children;
}
}
(2)巧用好handle机制可以使客户端跟服务端交互更容易
这个阶段的难点就是客户端与服务器打交道问题,一个常常发生的问题就是线程崩溃,子线程还要将数据传递给主线程。(当时卡在如何将子线程中两个或两个以上的数据传递给主线程,绕了个半天,后来发现,用swicth语句轻松将其解决了)
解决方式:利用handler方式
异步任务AsyncTask
区别点:( )
关键性核心代码:
// 主线程消息处理中心
mainHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
Toast.makeText(FacilityActivity.this, "联网成功", 1).show();
break;
case 0:
Toast.makeText(FacilityActivity.this, "联网成功失败", 1).show();
break;
case 3:
// 得到保存的xml文件
File file = new File("/data/data/com.zknu.zhihui",
"myxml.xml");
// 定义puller解析的流
InputStream is = null;
InputStream is1 = null;
try {
is = new FileInputStream(file);
is1 = new FileInputStream(file);
// Pull解析mxl文档 将解析出来的数据放到parents和children容器了
parents = XmlPull.getParents(FacilityActivity.this, is);
children = XmlPull.getChildren(FacilityActivity.this,
is1);
is.close();
is1.close();
} catch (Exception e) {
e.printStackTrace();
}
// System.out.println("parents " + parents.size());
// System.out.println("children " +
// children.get(0).size());
// 动态刷新适配器
myAdapter.notifyDataSetChanged();
break;
case 007:
SendData(SendBuf, 6);
default:
break;
}
}
};
(3)socket通讯
(请看我下一篇博客)
未完待续未完待续未完待续未完待续未完待续未完待续未完待续未完待续未完待续!!!!!!!!!!
这个是项目初级完成的效果,代码很珍贵哦,欢迎提意见