上篇文章学习了Thread和Runnable的方式实现异步。
Android异步学习(一):Thread和Runnable
Android异步学习(二):Handler和AsyncTask
Android异步学习(三):RxAndroid
这次学习Handler和AsyncTask。先来说明一下Handler和AsyncTask。
AsyncTask
AsyncTask是由Android提供的轻量级异步工具。
- 优点:使用简单,提供过程主要步骤的接口
- 缺点:多个异步同时进行就会复杂
Handler
Handler通常是通过重载handlerMessage方法接收工作线程的消息,内部进行对主线程进行UI操作。通过sendMessage发送消息。
下面以下载业务为例,分别说明AsyncTask和Handler
AsyncTask
- 布局文件
定义了一个button和progress bar,负责开始和进度
<Button
android:id="@+id/btn_start"
android:layout_width="160dp"
android:layout_height="60dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_dashboard"
app:layout_constraintEnd_toEndOf="parent"
android:text="Start" />
<ProgressBar
android:id="@+id/pb_down"
android:layout_width="match_parent"
android:layout_height="24dp"
android:layout_marginTop="10dp"
android:layout_marginHorizontal="20dp"
android:max="100"
android:progressDrawable="@drawable/progressbar_bg"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
app:layout_constraintTop_toBottomOf="@+id/btn_start"/>
- DownAsyncTask
public class DownAsyncTask extends AsyncTask<Integer, Integer, String> {
private ProgressBar progressBar;
private Context context;
public DownAsyncTask(Context context, ProgressBar progressBar) {
super();
this.context = context;
this.progressBar = progressBar;
}
// 该方法在后台执行下载的操作
@Override
protected String doInBackground(Integer... integers) {
int i = 0;
for (; i < 101; i++) {
// 通过该方法可以触发onProgressUpdate,从而更新UI
publishProgress(i);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 返回值是onPostExecute的参数,可以在onPostExecute中显示进度
return String.valueOf(i);
}
@Override
protected void onPreExecute() {
super.onPreExecute();
Toast.makeText(context, "开始下载", Toast.LENGTH_SHORT).show();
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Toast.makeText(context, "下载完成", Toast.LENGTH_SHORT).show();
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
// 更新UI
progressBar.setProgress(values[0]);
}
}
- Activity/Fragment
最后就是使用,在定义的Button的Click监听中执行execute方法就可以了。
DownAsyncTask downAsyncTask = new DownAsyncTask(this, mProgressBar);
downAsyncTask.execute();
- Handler
还是上面的布局文件,Handler有两种方式进行实现
- 方式一 Post(Runnable)
- 先创建工作线程实现Runnable接口,在run中进行耗时操作。
- 然后在利用handler的post方法,在实现Runnable接口的run方法中更新UI。
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_start:
new Thread(new Runnable() {
@Override
public void run() {
// TODO下载操作
int i = 0;
for (; i < 101; i++) {
final int finalI = i;
handler.post(new Runnable() {
@Override
public void run() {
// TODO 更新UI
mProgressBar.setProgress(finalI);
}
});
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
break;
-
方式二 Message
- 创建工作线程继承Thread,重写run方法执行耗时操作,在工作线程中通过handler.sendMessage方法发送Message。
- 创建Handler,重写handlerMessage方法,在这里接收工作线程发送的Message,根据业务执行更新UI操作。
class DownThread extends Thread {
@Override
public void run() {
super.run();
int i = 0;
for (; i < 101; i++) {
handler.sendEmptyMessage(i);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_start:
new DownThread().start();
handler = new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
// 这里使用msg.what作为进度更新UI
mProgressBar.setProgress(msg.what);
}
};
break;
以上就是AsyncTask和Handler的基本使用方式。下篇学习RxAndroid的使用。