首先是郭神的话:“和许多其他的GUI库一样,android的UI也是线程不安全的。也就是说,如果想要更新应用程序里的UI,则必须在主线程中进行,否则就会出现异常。对于这种情况,安卓提供了一套异步消息处理机制,完美地解决了在子线程中进行UI操作的问题”。

具体就是两种方式:

Handler和AsyncTask这两个类。

Handler的代码直接写在gitHub里面了,为什么我觉得Handler要比AsyncTask简单不少?

Looper容器暂时不管了。。

1.Handler

Handler放在UI线程里,作为一个内部类,里面准备一个handleMessage方法,进行UI更新操作,而发出UI更新操作的请求来自新的线程,该线程新生成一个Messasge对象,Message对象可以包含what、obj等变量,装一些数据。最后用sendMessage方法把message(装好了数据的)发出去,Handler内部类的handleMessage方法就会立刻(或许要排队)执行。个人理解是把更新UI操作的请求先排好队,装进一个消息队列,然后用Looper一个一个往外取,可以说是将子线程里的一些请求交给了一个Handler去处理。当然更底层的知识暂时还没时间学习。

另外就是什么时候考虑可以将Handler作为一个外部类提取出来,老是内部类还说明自己java不过关。




2.AsyncTask<Params, Progress, Result>

gitHub代码

使用AsyncTask之前,先归纳下网络访问数据的方法:

使用HttpURLConnection或者HttpClient(Deprecated),具体的我之前都有总结。

直接回到AsyncTask<Params, Progress, Result>这个类

在主线程里调用mTask.execute()方法,execute()方法接收的参数类型为Params类型。

主线程里还可以调用mTask.cancel(true)方法,这会调用mTask里面的onCancelled方法,具体onCancelled里面的实现需要自己去写。


此外就是onPreexecuted、doInBackground、onProgressUpdate、onPostExecute、onCancelled这五个方法的实现了。

注意,这里五个方法都不可以在代码里直接调用,还有就是这五个方法里只有doInBackground是在子线程里面执行的。

doInBackground(String... params)

使用的时候使用params[0]即可。


第二个泛型由PublishProgress(int XXX)方法接收

doInBackground这个方法里面通过一个publishProgress(int xxx)方法,接收了一个int类型参数,也就对应着第二个泛型Integer了。

这个int类型的参数会被传给onProgressUpdate方法,使用的语句如下

progressBar.setProgress(progresses[0]);  
textView.setText("loading..." + progresses[0] + "%");


第三个泛型应该是对应着result,这个是在onPostExecute(String result)方法里面接收的。

使用语句如下:

textView.setText(result);



AsyncTask可以用于后台实现进度条

自己找到的文章大部分都是使用一个HtttpClient去request百度的首页,然后使用一个进度条展示读取response的进度的。