Android 之 AsyncTask 讲解
人生第一篇博文,一名大学女码农的新开始 !
先来讲讲什么是 AsyncTask
- 由于Android 的用户界面是一种单线程模型 ,要求UI(界面)的更新只能在主线程(UI线程)中完成,因此,为了不阻塞主线程,异步处理是不可避免的。
- AsyncTask异步任务 ,是Android提供的轻量级的异步处理机制,它是一个抽象类,可以通过继承该类得到的子类来实现异步操作,并能反馈当前异步执行的程度(进而可实现UI进度的更新),最后反馈执行的结果给UI主线程。
- 由于AsyncTask是一个抽象类,所以如果想要使用它,就必须要创建一个子类去继承它。在继承时为AsyncTask类指定的三个泛型参数的用途如下:
- Params:启动任务执行的输入参数,比如HTTP请求
- Progress: 后台任务执行的进度。
- Result: 后台执行任务最终返回的结果,比如String等…
再来说说AsyncTask的主要调回方法
使用AsyncTask异步任务机制必须要重写的方法:
- doInBackground(Params…): 后台执行,比较耗时的操作都可以放在这里。注意这里不能直接操作UI。此方法在后台线程执行,完成任务的主要工作,通常需要较长时间。在执行过程中可以调用,publishProgerss(Progress…)来更新任务的进度。
根据需要选择重写AysncTask的方法:
- onPostExecute(Result): 相当于Handler处理UI的方式,当doInBackground()方法完成后,系统会自动调用OnPostExecute()方法,并将doInBackground()方法的返回值传给该方法。在这里可以使用doInBackground()方法得到的结果处理操作UI。此方法在主线程执行。
- onProgressUpdate(Progress…): 在doInBackground()方法中调用publishProgress()方法更新任务的执行进度,将触发该方法。该方法在主线程中执行,用于显示任务执行的进度。
- onPreExecute(): 方法将在后台任务执行前被调用。通常该方法用于完成一些初始化准备工作,比如界面上显示进度条等。此方法在主线程中执行。
- onCancelled(): 异步任务取消时要做的操作。
示列代码之利用AysncTask更新UI界面,模拟展示下载进度。
- 布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/btn1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="EXECUTE"/>
<Button
android:id="@+id/btn2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="CANCEL"
android:enabled="false"/>
<ProgressBar
android:id="@+id/bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:progress="0"
android:max="100"
style="?android:attr/progressBarStyleHorizontal" />
<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
- 控制文件关键代码
public class MainActivity extends Activity {
private static final int STATE_FINISH = 1;
private static final int STATE_ERROR = -1;
private Button exe,cancel;
private ProgressBar progressBar;
TextView textView;
private MyTask myTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
exe = findViewById(R.id.btn1);
cancel = findViewById(R.id.btn2);
progressBar = findViewById(R.id.bar);
textView = findViewById(R.id.tv);
exe.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
myTask = new MyTask();
myTask.execute();
exe.setEnabled(false);
cancel.setEnabled(true);
}
});
cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
myTask.cancel(true);
}
});
}
private class MyTask extends AsyncTask<String,Integer,Integer>{
@Override
protected void onPreExecute() {
textView.setText("downloading....");
}
@Override
protected Integer doInBackground(String... strings) {
for (int i = 0; i <= 100; i+=10) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
return STATE_ERROR;
}
publishProgress(i);
}
return STATE_FINISH;
}
@Override
protected void onProgressUpdate(Integer... values) {
progressBar.setProgress(values[0]);
textView.setText("downloading..." + values[0] + "%");
}
@Override
protected void onPostExecute(Integer result) {
int state = result.intValue();
if (state == STATE_FINISH){
textView.setText("done");
}else if(state == STATE_ERROR){
textView.setText("error");
}
exe.setEnabled(true);
cancel.setEnabled(false);
}
@Override
protected void onCancelled() {
textView.setText("cancelled!");
progressBar.setProgress(0);
exe.setEnabled(true);
cancel.setEnabled(false);
}
}
}
- 效果展示
初始布局界面:
点击上面运行按钮执行情况:
点击下面取消按钮的执行情况:
小结
第一次写博文,若该文章有任务问题,望各位大佬们指出。如有阅读起来不顺心的地方也请各位朋友一 一指出,后期会一 一改正。