Android中常用到的子线程更新UI的方法
1.Handler
1.通过handler.post
handler.post(new Runnable() {
@Override
public void run() {
// update UI
}
});
2.通过发送Message
Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
switch(msg.what){
case 0:
// update UI
break;
}
}
};
...
handler.sendEmptyMessage(0);
2.activity.runOnMainThread
runOnUiThread(new Runnable() {
@Override
public void run() {
// update UI
}
});
3.view.post
view.post(new Runnable() {
@Override
public void run() {
// update view
}
});
4.AsyncTask
AsyncTask是一个抽象类,我们必须写一个子类继承它,在子类中完成具体的业务下载操作。为了对各种情况更好的封装,AsyncTask抽象类指定了三个泛型参数类型,如下:
public abstract class AsyncTask<Params, Progress, Result>
Params:开始异步任务执行时传入的参数类型,即doInBackground()方法中的参数类型;
Progress:异步任务执行过程中,返回下载进度值的类型,即在doInBackground中调用publishProgress()时传入的参数类型;
Result:异步任务执行完成后,返回的结果类型,即doInBackground()方法的返回值类型;
AsyncTask的回调方法
一个基本的AsyncTask有如下几个回调方法:
(1)onPreExecute():在执行后台下载操作之前调用,运行在主线程中;
(2)doInBackground():核心方法,执行后台下载操作的方法,必须实现的一个方法,运行在子线程中;
(3)onPostExecute():后台下载操作完成后调用,运行在主线程中;
因此,AsyncTask的基本生命周期过程为:onPreExecute() –> doInBackground() –> onPostExecute()。其中,onPreExecute()和onPostExecute()分别在下载操作前和下载操作后调用,同时它们是在主线程中进行调用,因此可以在这两个方法中进行UI的更新操作,比如,在onPreExecute()方法中,将下载等待动画显示出来,在onPostExecute()方法中,将下载等待动画进行隐藏。
如果我们想向用户展示文件的下载进度情况,这时,我们可以在doInBackground()下载操作中,调用publishProgress(),将当前进度值传入该方法,而publishProgress()内部会去调用AsyncTask的另一个回调方法:
(4)onProgressUpdate():在下载操作doInBackground()中调用publishProgress()时的回调方法,用于更新下载进度,运行在主线程中;
另外,如果需要取消当前任务,可以调用
* @param mayInterruptIfRunning true if the thread executing this
* task should be interrupted; otherwise, in-progress tasks are allowed
* to complete.
*
* @return false if the task could not be cancelled,
* typically because it has already completed normally;
* true otherwise
*
public final boolean cancel(boolean mayInterruptIfRunning)
但是要注意的是,cancel方法并没有能力真正去取消一个任务,其实只是设置这个任务的状态为取消状态,我们需要在doInBackground()下载中进行检测,一旦检测到该任务被用户取消了,立即停止doInBackground()方法的执行。