AsyncTask处理异步任务
在之前学习了用Handler来执行异步操作(安卓handler线程通信以及源码学习),如果还有不会用的小伙伴可以去看看。今天来学习一下另一种执行异步操作的方法——AsyncTask处理异步任务,老规矩,通过一个demo来学习,先贴上效果图:
实现的功能就是,用AsyncTask执行一个异步操作,模拟异步请求数据,并实时更新progressbar。
布局代码:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/title" />
<ProgressBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Base.Widget.AppCompat.ProgressBar.Horizontal"
android:id="@+id/prgbar"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/start_btn"
android:text="start"/>
</LinearLayout>
布局上有一个TextView来模拟执行异步操作前后对UI的操作,有个进度条,还有个按钮来控制异步任务的开始。
下面先贴上activity代码:
public class MainActivity extends AppCompatActivity {
private TextView mTitle;
private ProgressBar mProgbar;
private Button mBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTitle = findViewById(R.id.title);
mProgbar = findViewById(R.id.prgbar);
mBtn = findViewById(R.id.start_btn);
mBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MyAsyncTask task = new MyAsyncTask(mTitle,mProgbar);
task.execute(1);
}
});
}
}
逻辑很简单,点击按钮开始执行异步任务,剩下的交给AsyncTask来完成,所以在这里单独写了一个类:
/**
* AsyncTask三个参数:
* 第一个是执行耗时操作时需要从外部传入的参数
* 第二个是更新Progressbar时传递的参数
* 第三个是doInBackground()方法执行完后返回的参数
*/
public class MyAsyncTask extends AsyncTask<Integer,Integer,String> {
private TextView mTextView;
private ProgressBar mPrgbar;
public MyAsyncTask(TextView mTextView, ProgressBar mPrgbar) {
this.mTextView = mTextView;
this.mPrgbar = mPrgbar;
}
/**
* onPreExecute()方法调用之后调用这个方法
* 运行在子线程中 进行一些耗时操作
* 调用方法publishProgress()更新Progressbar
* @param integers
* @return
*/
@Override
protected String doInBackground(Integer... integers) {
for (int i = 10; i <= 100; i+=10) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
publishProgress(i);
}
return "完成";
}
/**
* 在执行耗时操作之前调用
* 此方法在ui线程中执行 可以在此进行一些ui上的操作
*/
@Override
protected void onPreExecute() {
super.onPreExecute();
mTextView.setText("异步线程执行中...");
}
/**
* doInBackgroud()方法执行完后调用此方法
* 在ui线程中执行
* @param s——接收doInBackgroud()方法返回的值
*/
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
mTextView.setText(s);
}
/**
* 根据doInBackgroud()方法中调用publishProgress()传进来的参数更新progressbar
* @param values 接收publishProgress()传过来的参数
*/
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
mPrgbar.setProgress(values[0]);
}
}
这个类继承自AsyncTask,重写了onPreExecute()
、doInBackground()
、onProgressUpdate()
和onPostExecute()
四个方法来完成整个异步过程。
下面对这个类中每个方法进行一个学习总结:
首先在类中定义了两个全局变量,由构造方法传进来的两个控件赋值给全局变量,拿到了布局中的控件,接下来就是AsyncTask中的方法使得异步任务的完成了。
onPreExecute()
:在执行异步任务时,最先调用的就是此方法,此方法在ui线程中执行,可以对ui进行一些初始化的操作;
doInBackground()
:在执行完上面方法后就调用了这个方法,这个方法是在子线程中运行的,所以耗时操作也是在这个方法里面执行,同时,这个方法中可以调用方法publishProgress()
发送进度,最后这个方法执行完后有个返回值,将在后面的方法用到;
onProgressUpdate()
:在publishProgress()
方法被调用后,这个方法将被主线程调用去更新ProgressBar,所以这个方法是在主线程中运行;
onPostExecute()
:在doInBackground()
方法执行完后,这个方法将被调用,其传入的参数就是doInBackground()
方法返回的参数。在这里我只是在耗时操作完成后做了一个简单的setText()操作,当然,在项目开发中,可以在这里设置一个监听或者发送一个事件,然后在activity中去为所欲为。
上面就是对各个方法的一个学习总结。此外,在继承的AsyncTask类中传入了三个泛型参数:
Params:执行异步操作时需要从外部传入的参数,比如url;
Progress:异步操作进行中更新ProgressBar时传递的参数;
Result:doInBakcground()方法执行完成后返回的参数,以及onPostExecute()方法中传入的参数。
以上就是本次对AsyncTask处理异步操作的学习,在此记录一下。