一、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();