在android开发中我们经常会遇到一些耗时操作,比如,打开一个Activity后,从本地数据库读入数据等:
一、Java的Thread
我们可以使用Java自带的Thread或者继承Runnable来实现新开一个线程来执行这些耗时操作。
但是这样有一个问题,就是我们执行这些耗时操作之后往往要对界面上的View进行更新,但是我们在这些新开的线程当中是无法对View进行直接操作的(因为View的更新只能在android UI主线程进行操作)
当然,如果你非要使用Java的Thread,使用runOnUiThread也可以解决问题:
new Thread(new Runnable)
{
public viod run()
{
getActivity().runOnUiThread(new Runnable()
{
@Override
public void run()
{
imageCollectorView.addImage(bitmap);
}
});
}
}
同时,andorid本身还给我们提供了2个封装好了的方法来解决这个问题
二、Handler
Handler handler = new Handler(){
public void handleMessage(Message msg)
{
switch(msg.what)
{
case UPDATE_VIEW:
tvText.setText("1234");
break;
default:
break;
}
}
}
····
new Thread(new Runnable)
{
public void run()
{
doSomething(); //耗时操作
Message message = new Message();
message.what = UPDATE_VIEW;
handler.sendMessage(message);
}
}.start();
我们在新开的Thread中中执行耗时操作,然后最后发送一条Message给Handler,Handler接收到之后对View进行更改,注意:只要Handler是在主线程创建的,那么handleMessage(Message msg)方法也是在主线程中执行,也就可以对View进行直接操作。
三、AsyncTask
这是android封装完毕的一个异步消息处理机制。
四个主要的方法:
- onPreExecute() : 在任务执行之前进行页面初始化工作,比如显示一个进度对话框(这个方法应该也是可以直接对View进行操作)
- doInBackground() : 在这里执行耗时操作,并且可以调用publishProgress() 来更新进度条,在这里返回的参数会被后面的onPostExecute()方法当做参数传入
- onProgressUpdate() : 更新UI
- onPostExecute : 最后执行的函数方法,通常用来做收尾工作,例如关闭进度条,显示“任务成功”等
这里简单介绍一下如何将一个下载任务的进度显示在进度条上(一些无关的代码没写):
protected void onPreExecute(){
progressDialog.show(); //显示进度条
}
protected void doInBackground(){
while(true)
{
int downloadPer=doDownload();
publishProgress(downloadPer); //更新进度条
if(downloadPer>=100)
break;
}
}
protected void onProgressUpdae(Integer··· values){
progressDialog.setMessage("per is " + values[0] );
}
protected void onPostExecute(···){
····
}
但是我们发现如果后台线程的逻辑如果更加复杂之后,对后台的线程操作会变得非常难,所以我们引入了rxJava&rxAndroid,详见我的其他博文