RSS Reader实例开发之联网开发
来源:互联网 发布:专业网络推广 编辑:程序博客网 时间:2024/05/16 09:06
在OPhone应用程序中,如果我们要做一些费时的操作,例如,从网络获取数据,就不能将这些操作放在普通的处理UI的逻辑中,否则,主线程一旦执行耗时任务,将无法响应用户的任何操作,OPhone系统会判定该应用程序已经无法正常响应,并提示用户强行关闭该应用程序:
RSS Reader需要从网络获取RSS的最新内容,自然需要使用多线程来实现。由于OPhone系统基于Java 5虚拟机和标准库,因此,多线程机制和Java 5完全相同,可以直接启动一个新的Thread。
RSS Reader利用HTTP GET方式读取RSS,可以直接利用java.net包提供的URL、HttpURLConnection等类来实现该功能,不必依赖任何第三方库,一段简单的代码如下:
在运行上述代码前,我们需要告诉OPhone系统,RSS Reader应用需要INTERNET权限,因此,务必在AndroidManifest.xml中添加权限声明:
请注意:没有声明INTERNET权限就运行联网代码会导致应用程序被异常关闭。
当后台线程获取到数据,需要更新UI时,千万不可直接在后台线程对UI组件进行操作,否则,你会得到一个如下图所示的警告,然后,应用程序被强制关闭:
熟悉桌面UI开发的开发者应该知道,对UI操作必须严格串行化,即只能通过主线程完成。如果多个线程同时对UI进行操作,将产生不可预料的后果。在OPhone系统中,对UI操作时,会检查当前线程是否是主线程,如果不是,系统将报错,然后强行关闭应用程序。
使用Message更新UI
为了能让后台线程通知主线程更新UI,OPhone系统提供了一个Handler类来处理消息,所有对UI更新的请求可以通过发送消息给Handler,在Handler的消息处理代码中,就可以安全地对UI进行操作了,因为Handler执行的消息处理代码是运行在UI主线程中的。
要异步更新UI,我们需要定义一个Handler实例,由于其无需更改,最好将其定义为final类型:
如果某个后台线程需要更新textView的内容,就可以发送一个消息来通知主线程更新:
在一个Activity中,可能需要处理多种自定义消息,Message.what字段就是用来区分消息类型的,消息常量可以自定义,只要保证各个常量的值唯一即可。Message还可以携带任意的Object来传递数据,例如,上述代码通过msg.obj = "Data updated!"来传递一个字符串,当Handler处理消息时,它会将TextView的内容更新。
使用AsyncTask
从1.5版本开始,为了更简化异步任务的执行,OPhone系统引入了新的AsyncTask类,使用AsyncTask,我们可以更加简单地实现异步线程,并且避免了使用Handler处理Message的麻烦。
AsyncTask基于Java 5的java.util.concurrent库,提供了基于线程池的调度功能,当同时运行多个小任务时,每个任务不必单独创建和销毁线程,而是通过ThreadPoolExecutor调度,重用线程池里的空闲线程,执行效率更高。
要使用AsyncTask,首先从AsyncTask派生一个子类。注意到AsyncTask需要3个泛型参数,分别代表输入、进度条和结果。假定我们的输入是一个String类型的URL地址,进度条通常是ProgressDialog的实例,结果是从URL读取的网页内容,这里用一个String表示,则定义AsyncTask如下:
AsyncTask必须在主线程中创建,同时必须在主线程中通过execute()方法调度,后台线程将执行doInBackground()方法,当该方法完成时,主线程将得到通知,并执行onPostExecute()方法。由于onPostExecute()方法是在主线程中执行的,因此,可以安全地在这个方法中更新UI。假定Activity包含一个id为textView的TextView,以上代码执行效果如下:
执行定时任务
在RSS Reader中,我们需要定期从网络读取RSS的最新内容,所以需要一个定期触发的调度器,最简单的方法是使用Java标准库的Timer,我们只需要实现TimerTask,就可以完成该功能。
使用Timer时需要注意,Timer本身会启动一个线程,如果在TimerTask的run()方法中抛出了任何异常,都会导致Timer线程终止,结果是无法继续执行定时任务。例如,以下代码:
当TimerTask执行到第10次时,将抛出RuntimeException异常,结果,Timer线程终止,你可以看到以下输出:
因此,务必使用try...catch处理TimerTask的run()方法的所有RuntimeException异常。
除了Timer外,OPhone系统本身还提供了另一种定时执行任务的机制,这就是利用sendMessageDelayed(Message, long)方法,通过延迟发送消息来模拟定期调度。这种方法依赖OPhone应用程序的消息处理机制,实现起来更简单,推荐采用。
RSS Reader就采用了sendMessageDelayed(Message, long)方法,实现定期读取RSS的功能。
在MainActivity中,我们定义一个MSG_TIMER常量,然后,实例化一个Handler来处理消息队列:
在refreshFeeds()方法中,我们通过AsyncTask在后台读取RSS。当读取到RSS后,调用sendMessageDelayed(Message, long)发送下一次MSG_TIMER的触发消息:
MainActivity首次运行时,需要调用一次refreshFeeds()方法,才能实现正常触发。首次调用refreshFeeds()代码可以写到MainActivity的onCreate()方法中。每隔60秒,就会触发一个MSG_TIMER消息,这样,我们就实现了定期读取Feed的功能。
updateUI()方法负责更新ListView的列表项,我们还需要解析从网络读取的XML格式的RSS,稍后,我们会编写该功能。
- RSS Reader实例开发之联网开发
- RSS Reader实例开发之系统设计
- Rss Reader实例开发之Xml与RSS解析
- RSS Reader实例开发之解析XML和使用WebView
- RSS Reader实例开发之存储本地数据
- RSS Reader实例开发之存储本地数据
- RSS Reader实例开发之使用Service组件
- RSS Reader实例开发之使用Service组件
- d-RSS-Reader基本开发完毕
- rss 开发实例 1 AbstractFeedServlet
- RSS 开发
- RSS 开发
- 阅读之选:RSS Reader完全指南
- 利用J2ME开发联网程序实例
- Django开发之添加RSS订阅源
- rss 开发实例2 getFeed()方法得实现
- Flask MVVM 开发(vue.js) 实例 -- 微信公从号RSS
- J2ME最佳实践之联网开发
- jQuery写的简单投票
- ico图标
- spring security 3 中使用自定义数据库来设置权限
- HiDef: 高效初始化常量
- Symbian发送短信完整代码
- RSS Reader实例开发之联网开发
- .NET之对接口和抽象类(转载)
- 互动网计算机频道图书7日销售排行(06.29-07.05)
- 基于第三方软件开发的策略探讨(2)
- 程序员需要看的书籍
- 项目需求分析和行政人事哪个有前途,更适合女生一些?
- 说说大型高并发高负载网站的系统架构
- 在OSGi container中运行bundle时无法获取derby的数据库连接
- XHProf