(1)作用:
1、执行耗时操作
2、实现工作线程与主线程之间的通信
(2)示例:
public class MainActivity extends AppCompatActivity {
private Button mBtStart;
private TextView mTvProgress;
private ProgressBar mProgress;
private Button mCencele;
//线程
private MyAsyncTask mAsyncTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBtStart = (Button) findViewById(R.id.bt_start);
mTvProgress = (TextView) findViewById(R.id.tv_progress);
mProgress = (ProgressBar) findViewById(R.id.progress);
mCencele = (Button) findViewById(R.id.cencele);
mAsyncTask=new MyAsyncTask();
//开始
mBtStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mAsyncTask.execute();
}
});
//取消
mCencele.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//取消一个正在执行的任务,这是会调用到onCancelled()
mAsyncTask.cancel(true);
}
});
}
//参数为3种泛型类型
//整体的作用:控制AsyncTask子类执行线程任务时各个阶段的返回类型
//参数1、Params:开始异步任务执行时传入的参数类型,对应excute()中传递的参数
//参数2、Progress:异步任务执行过程中,返回下载进度值的类型
//参数3、Result:异步任务执行完成后,返回的结果类型,与doInBackground()的返回值类型保持一致
private class MyAsyncTask extends AsyncTask<String,Integer,String>{
//作用:执行线程任务前的操作,用于界面的初始化,如显示进度条的对话框
@Override
protected void onPreExecute() {
mTvProgress.setText("加载中");
}
//作用:接收输入的参数、执行任务中的耗时操作,返回 线程任务执行的结果
@Override
protected String doInBackground(String... strings) {
int count=0;
int add=1;
while (count<99){
count+=add;
//调用publishProgress()显示进度条,之后将执行onProgressUpdate()
publishProgress(count);
try {
//模拟耗时操作,休眠1秒
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
//作用:在主线程 显示线程任务执行的进度
@Override
protected void onProgressUpdate(Integer... values) {
mProgress.setProgress(values[0]);
mTvProgress.setText("当前加载的进度。。。"+values[0]+"%");
}
//作用:接收线程任务执行结果、将执行结果显示到UI组件
@Override
protected void onPostExecute(String s) {
//执行完成,更新UI
mTvProgress.setText("加载完成");
}
//作用:将异步任务设置成取消状态
@Override
protected void onCancelled() {
mTvProgress.setText("已经取消");
}
}
@Override
protected void onDestroy() {
mAsyncTask.cancel(true);
super.onDestroy();
}
}
运行结果:
当再次点击加载数据时会报错:
(3)方法的执行顺序:
基本使用:execute > onPreExecute > doInBackground > onPostExecute
显示进度:execute > onPreExecute > doInBackground > publishProgress() > onPostExecute > onProgressUpdate
执行线程任务时终止:execute > onPreExecute > doInBackground > onCancelled
基本使用:execute > onPreExecute > doInBackground > onPostExecute
显示进度:execute > onPreExecute > doInBackground > publishProgress() > onPostExecute > onProgressUpdate
执行线程任务时终止:execute > onPreExecute > doInBackground > onCancelled
(4)注意:
1、执行execute(Params... params),必须在UI线程中调用。同一个AsyncTask示例对象只能执行1次,若执行2次就会抛出异常。
2、因为AsyncTask不与任何组件绑定生命周期,所以在Activity或者Fragment中的 onDestory() 调用 cancel()。
3、内存泄漏。若As云南菜Task被声明为Activity的非静态内部类当Activity被销毁的时,会因为AsyncTask保留对Activity的引用导致Activity无法被回收,最终引起内存泄漏。所以使用AsyncTask时,AsyncTask被声明为Activity的静态内部类。
4、线程任务结果丢失:当Activity重新创建时(屏幕旋转 / Activity被意外销毁时后恢复),之前运行的AsyncTask(非静态的内部类)持有的之前Activity引用已无效,故复写的onPostExecute()
将不生效,即无法更新UI操作。所以,在Activity恢复时的对应方法 重启 任务线程