一、Handler消息处理器:android.os.Handler
用来发送和接收处理消息,一般用来处理子线程发来的消息。
当应用程序启动时,Android首先会开启一个主线程(也就是UI线程),主线程为管理界面中的UI控件,进行事件分发,比如说,你要是点击一个Button,Android会分发事件到Button上,来响应你的操作。 如果此时需要一个耗时的操作,例如:联网读取数据,或者读取本地较大的一个文件的时候,你不能把这些操作放在主线程中,,如果你放在主线程中的话,界面会出现假死现象,如果5秒钟还没有完成的话,会收到Android系统的一个错误提示 "强制关闭", 这个时候我们需要把这些耗时的操作,放在一个子线程中,因为子线程涉及到UI更新,Android主线程是线程不安全的,也就是说,更新UI只能在主线程中更新,子线程中操作是危险的.这个时候,由于Handler运行在主线程中(UI线程中), 它与子线程可以通过Message对象来传递数据,这个时候,Handler就承担着接受子线程传过来的Message对象(里面包含数据) ,把这些消息放入主线程队列中,配合主线程进行更新UI。
实现:
1、在主线程中创建:
mHandler = new Handler()
{
@Override
public void handleMessage(Message msg)
{//重载消息处理函数
super.handleMessage(msg);
do();//在该函数中对消息处理
}
};
2、在子线程中发送消息:
mHandler.sendMessage(msg);
3、消息生成
Message msg = new Message();//创建一个新消息,需要new重新开辟空间
Message msg = mHandler.obtainMessage();//从消息处理器的消息池里取出一个,不需要new,效率高。
当然消息可以加参数,处理消息时也可以获取这些参数进行处理。
二、Thread子线程处理类:java.lang.Thread,这个属于java中的类,不是android的
1、创建线程:此时只是创建,线程还没有启动
Thread thread = new Thread(new Runnable()
{
public void run()
{//线程运行函数
do();//线程中进行相关处理
}
});
其实,这个代码这样写就明白了
//先创建运行接口,在接口里指明运行函数
Runnable runnable = new Runnable()
{
public void run()
{//线程运行函数
do(); //线程中进行相关处理
}
}
//以这个运行接口为参数创建线程,当线程启动时则运行接口里的run函数
Thread thread = new Thread(runnable);
2、启动线程:
thread.start();
三、在程序中创建菜单:android.view.Menu
android程序一般没有菜单栏,但是可以通过手机面板上的menu键实现菜单的功能。Android一共有三种形式的菜单: 1.选项菜单(optinosMenu) 2.上下文菜单(ContextMenu) 3.子菜单(subMenu)
其中最常用的就是选项菜单(optionsMenu), 该菜单在点击 menu 按键后会在对应的Activity底部显示出来。Activity有一套机制来实现对菜单的管理。
选项菜单实现:
1、public boolean onCreateOptionsMenu(Menu menu):此方法用于初始化菜单,其中menu参数就是即将要显示的Menu实例。返回true则显示该menu,false 则不显示;
(只会在第一次初始化菜单时调用,系统提供此运行时自动调用的函数,方便创建菜单)
添加菜单项:menu.add((int groupId, int itemId, int order, charsequence title) .setIcon(drawable ID)
add()方法的四个参数,依次是:
1、组别,如果不分组的话就写Menu.NONE,
2、Id,这个很重要,Android根据这个Id来确定不同的菜单
3、顺序,哪个菜单项在前面由这个参数的大小决定
4、文本,菜单项的显示文本
add()方法返回的是MenuItem对象,调用其setIcon()方法,为相应MenuItem设置Icon
2、菜单响应函数:public boolean onOptionsItemSelected(MenuItem item)
菜单项被点击时调用,也就是菜单项的监听方法。
3.public void onOptionsMenuClosed(Menu menu):每次菜单被关闭时调用.
(菜单被关闭有三种情形,menu按钮被再次点击、back按钮被点击或者用户选择了某一个菜单项)
四、RSS源解析的实现
1、要解析的RSS源文件格式样例
<rss version="2.0">
<channel>
<title>
<![CDATA[IT-新浪博客]]>
</title>
<image>
<title>
<![CDATA[新浪博客频道]]>
</title>
<link>http://blog.sina.com.cn</link>
<url>http://www.sinaimg.cn/blog/main/index2010/blog_logo.png</url>
</image>
<description>
<![CDATA[IT博客列表]]>
</description>
<link>http://blog.sina.com.cn/lm/tech/</link>
<language>zh-cn</language>
<generator>WWW.SINA.COM.CN</generator>
<ttl>5</ttl>
<copyright>
<![CDATA[Copyright 1996 - 2013 SINA Inc. All Rights Reserved]]>
</copyright>
<pubDate>Fri, 23 Aug 2013 07:39:40 GMT</pubDate>
<category>
<![CDATA[]]>
</category>
<item>
<title>
<![CDATA[百度轻应用想要做什么]]>
</title>
<link>http://go.rss.sina.com.cn/redirect.php?url=http://blog.sina.com.cn/s/blog_88acd9c80101gld8.html</link>
<author>WWW.SINA.COM.CN</author>
<guid>http://go.rss.sina.com.cn/redirect.php?url=http://blog.sina.com.cn/s/blog_88acd9c80101gld8.html</guid>
<category>
<![CDATA[IT博客]]>
</category>
<pubDate>Fri, 23 Aug 2013 06:35:27 GMT</pubDate>
<comments></comments>
<description>
<![CDATA[]]>
</description>
</item>
<item>
<title>
<![CDATA[互联网理财:值得借鉴的美国平台样板]]>
</title>
<link>http://go.rss.sina.com.cn/redirect.php?url=http://blog.sina.com.cn/s/blog_bee732060101npb7.html</link>
<author>WWW.SINA.COM.CN</author>
<guid>http://go.rss.sina.com.cn/redirect.php?url=http://blog.sina.com.cn/s/blog_bee732060101npb7.html</guid>
<category>
<![CDATA[IT博客]]>
</category>
<pubDate>Fri, 23 Aug 2013 06:05:08 GMT</pubDate>
<comments></comments>
<description>
<![CDATA[]]>
</description>
</item>
</channel>
</rss>
2、实现表示每个RSS条目的类
//Rssitem信息,用于存放RSS的每一个item
public class RssItem
{
public static final String TITLE = "title";
public static final String PUBDATE = "pubDate";
//标题
private String title;
//详细内容
private String description;
//链接
private String link;
//来源
private String source;
//日期
private String pubDate;
//获得标题
public String getTitle() {
return title;
}
//设置 标题
public void setTitle(String title) {
this.title = title;
}
//取得详细信息
public String getDescription() {
return description;
}
//设置详细信息
public void setDescription(String description) {
this.description = description;
}
//取得链接
public String getLink() {
return link;
}
//设置链接
public void setLink(String link) {
this.link = link;
}
//取得来源
public String getSource() {
return source;
}
//设置来源
public void setSource(String source) {
this.source = source;
}
//取得日期
public String getPubDate() {
return pubDate;
}
//设置日期
public void setPubDate(String pubDate) {
this.pubDate = pubDate;
}
}
3、实现一个RSS源类
//RSS源类,用于存放一个RSS源的全部信息
public class RssFeed
{
//标题
private String title;//RSS源、频道的标题
//日期
private String pubdate;//RSS源、频道的发布日期
//条目数量
private int itemcount;
//用于存放RSS信息的列表
private List<RssItem> itemlist;
public RssFeed()
{
itemlist = new Vector<RssItem>(0);
}
//添加元素
public int addItem(RssItem item) {
itemlist.add(item);
itemcount++;
return itemcount;
}
//取得元素
public RssItem getItem(int location) {
return itemlist.get(location);
}
//取得所有列表需要的信息,存储到List
public List getAllItemsForListView()
{
List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
int size = itemlist.size();
for(int i=0; i<size; i++) {
HashMap<String, Object> item = new HashMap<String, Object>();
item.put(RssItem.TITLE, itemlist.get(i).getTitle());
item.put(RssItem.PUBDATE, itemlist.get(i).getPubDate());
data.add(item);
}
return data;
}
//取得标题
public String getTitle() {
return title;
}
//设置标题
public void setTitle(String title) {
this.title = title;
}
//取得日期
public String getPubdate() {
return pubdate;
}
//设置日期
public void setPubdate(String pubdate) {
this.pubdate = pubdate;
}
//取得数量
public int getItemcount() {
return itemcount;
}
//设置数量
public void setItemcount(int itemcount) {
this.itemcount = itemcount;
}
//获得信息数组
public List<RssItem> getItemlist() {
return itemlist;
}
//设置信息数组
public void setItemlist(List<RssItem> itemlist) {
this.itemlist = itemlist;
}
}
4、创建一个RSS数据SAX解析时的处理器类
使用一系列工厂方法生成了一个XMLReader对象,随后,要通过reader.setContentHandler方法,为这个reader设置了一个处理器。使用SAX的时候,解析器会对XML文档进行深度优先遍历,在遍历的时候,会根据条件调用处理器中的方法。也就是说在解析的时候,可以调用我们自己的方法。
通过这个类可以在解析的时候,把RSS源的信息,充填到RssFeed类对象中。然后通过这个类的public RssFeed getFeed()这个方法获取已经充填数据的RssFeed类对象。
//RSS数据SAX解析
public class RssHandler extends DefaultHandler
{
RssFeed rssFeed;
RssItem rssItem;
private static boolean a = false;
String lastElementName = "";
final int RSS_TITLE = 1;
final int RSS_LINK = 2;
final int RSS_DESCRIPTION = 3;
final int RSS_PUBDATE = 5;
int currentstate = 0;
public RssHandler() {
}
//返回rssFeed形式的信息
public RssFeed getFeed() {
return rssFeed;
}
//开始解析文档
public void startDocument()throws SAXException {
System.out.println("startDocument");
//实例化RssFeed类和RssItem类
rssFeed = new RssFeed();
rssItem = new RssItem();
}
//文档结束
@Override
public void endDocument() throws SAXException {
super.endDocument();
}
//开始解析标签
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException
{
super.startElement(uri, localName, qName, attributes);
//channel标签
if(localName.equals("channel")) {
currentstate = 0;
return;
}
//item标签
if(localName.equals("item")) {
rssItem = new RssItem();
return;
}
//title标签
if(localName.equals("title")) {
currentstate = RSS_TITLE;
return;
}
//详细信息标签
if(localName.equals("description")) {
//跳过第一次遇到的description标签
if(a == true) {
currentstate = RSS_DESCRIPTION;
return;
} else {
a = true;
return;
}
}
//链接
if(localName.equals("link")) {
currentstate = RSS_LINK;
return;
}
//日期
if(localName.equals("pubDate")) {
currentstate = RSS_PUBDATE;
return;
}
currentstate = 0;
}
//标签结束
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
//将信息添加到rssFeed中
if(localName.equals("item")) {
rssFeed.addItem(rssItem);
return;
}
}
//解析标签间的文本
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if(length <= 5) return ;
String theString = new String(ch, start, length);
switch (currentstate) {
//标题
case RSS_TITLE:
rssItem.setTitle(theString);
Log.e("title",theString);
currentstate = 0;
break;
//链接
case RSS_LINK:
rssItem.setLink(theString);
currentstate = 0;
break;
//详细信息
case RSS_DESCRIPTION:
System.out.println("RSS_DESCRIPTION=" + theString);
if(a == true) {
rssItem.setDescription(theString);
currentstate = 0;
}else {
a = true;
}
break;
//日期
case RSS_PUBDATE:
rssItem.setPubDate(theString);
currentstate = 0;
break;
default:
return;
}
}
}
5、实现解析
//根据URL实现解析
URL url = new URL(urlString);
//实例化SAX解析工厂类
SAXParserFactory factory = SAXParserFactory.newInstance();
//根据类工程创建SAX解析器
SAXParser parser = factory.newSAXParser();
//从SAX解析器获取XML阅读器
XMLReader xmlReader = parser.getXMLReader();
//挂接事件处理对象到xmlReader上
RssHandler rssHandler = new RssHandler();
xmlReader.setContentHandler(rssHandler);
//取得url网址内容,构造函数参数是字节流,它通过url.openStream()获取
InputSource is = new InputSource(url.openStream());
//解析url网址内容
xmlReader.parse(is);
//返回RSS信息
RssFeed rssfeed = rssHandler.getFeed();