《Android编程权威指南》第26~27章读书笔记

获取网络使用权限

清单文件中,添加:
<uses-permission android:name="android.permission.INTERNET"/>

线程与主线程

线程
线程是一个单一的执行序列。单个线程中的代码可以得到逐步执行。

主线程
每个Android应用的运行都是从主线程开始的。主线程处于一个无限循环的运行状态,等待用户或系统触发事件后,便负责执行代码,以响应事件。
事件处理的循环是的U相关代码得以顺利执行,保证任何事件处理都不会发生冲突,同时代码能够快速响应执行。

一般线程与主线程

使用XmlPullParser

XmlPullParser接口采用拉的方式从XML数据流中获取解析时间。Android内部也是用XmlPullParser接口来实例化布局文件。

XmlPullParser工作原理

使用AsyncTask

在doInBackground(...)等方法中更新UI,也就是在后台线程中更新UI,存在安全隐患;onPostExecute(...)在doInBackground(...)执行完毕之后才会执行,而且该方法在主线程而不是后台线程中运行,可以比较安全地更新UI。

同理,进度更新也属于UI更新,不应该在后台线程中进行,AsyncTask提供了publishProgress(...)和onProgressUpdate(...)。在后台线程中,从doInBackground(...)中调用publishProgress(...),onProgressUpdate(...)在主线程上被调用,更新UI。

注意:调用AsyncTask.cancel(boolean)撤销运行中的AsyncTask:
① cancel(false) 此时会设置isCancelled()状态为true,随后,AsyncTask会检查doInBackground(...)中的isCancelled()状态,然后选择提前结束运行;
② cancel(true) 此时会直接终止doInBackground(...)当前所在线程,该方法简单粗暴,应尽量避免使用。

Looper、Handler与HandlerThread

Android OS中,存在消息队列,使用消息队列的线程叫消息循环。消息循环会不断检查消息队列上是否有新消息。

消息循环由一个线程和一个Looper组成。Looper对象管理着线程的消息队列。主线程就是一个消息循环。

Message与message Handler
消息是Message类的一个实例,三个需要在定义时实现的变量:
① what:用户定义的int型消息代码,用来描述消息;
② obj:随消息发送的用户指定对象;
③ target:处理消息的Handler。

target是Handler类的一个实例。Message在创建时,会自动与一个Handler相关联。

一个Message仅仅与一个Handler相关联,一个Handler仅仅与一个Looper相关联,Looper拥有着整个Message队列。

Handler的使用:
① 调用Handler.obtainMessage(...)创建Message并传入其它Message字段,该方法会自动将Message的target设为该Handler;
注意:Handler.obtainMessage(...)从公共循环池里面获取Message,这样避免了创建新的Message对象,提高了效率。
② Message创建后,调用sendToTarget(...)将Message发送给Handler,Handler会将Message放置在Looper消息队列尾部;
③ Looper取得消息队列中的特定Message之后,会发送个Message的target,也就是Handler处理,一般在Handler.handleMessage(...)的实现方法中处理。

传递Handler:
HandlerThread在主线程完成任务的一种方式:让主线程将自身的Handler传递给HandlerThread。
任何已传出Handler负责处理的Message都将在主线程的消息队列中处理。

推荐阅读更多精彩内容