简介:
异步任务 (很多的网络相关开源框架,大多数都是使用这个)
thread(请求数据) + handler(发送数据到主线程)
说白了就是对前面的组合进行封装,简化程序员的开发
方法简介
onPreExecute
运行线程 主线程执行 运行时机 最先运行的方法,先于任务执行 , 一般在这里面执行一些初始化工作,包括弹出一个对话框,提示用户,目前将要执行耗时操作了。
doInbackground
运行的线程
在子线程中执行,一般多用于执行耗时操作
运行的时机
在onPreExecute执行完毕只有调用
方法参数
类上面定义的第一个泛型类型来定 参数是从execute里面传递过来的,是一个可变参数
方法返回值
类型有上面的第三个泛型来定义。
onProgressUpdate
运行的线程
在主线线程中执行,一般多用于更新进度
运行的时机
在调用 publishProgress的时候就执行了。 一般这个 publishProgress方法都是在doInbackground里面调用
方法参数
类上面定义的第二个泛型类型来定 参数是从publishProgress里面传递过来的,是一个可变参数
onPostExecute
运行的线程
在主线程执行,一般在这里要做UI的更新了
运行的时机
在doInbackground执行完毕只有调用
方法参数
类上面定义的第三个泛型类型来定 参数是从doInbackground的返回值传递过来的
举一个例子
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//new MyAsyncTask().execute(20,30,40);//这里面的值会传递到doInBackground里面去
MyAsyncTask task=new MyAsyncTask();
task.execute(20,30,40);
//task.cancel(true);//删除任务
}
public class MyAsyncTask extends AsyncTask<Integer, Integer, Integer> {
ProgressDialog dialog;
@Override
protected void onPreExecute() {
super.onPreExecute();
dialog=new ProgressDialog(MainActivity.this);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.show();
Log.d("tag","在主线程执行哦,并且最先执行");
}
@Override
protected Integer doInBackground(Integer... params) {//这里方法的类型,由AsyncTask<Integer, Integer, Integer>的第一个类型决定
for(int i=1;i<6;i++){
Log.d("tag",params[0]+"::"+params[1]);
Log.d("tag","doInBackground:"+Thread.currentThread().getName());
publishProgress(5,i);
SystemClock.sleep(2000);
}
return 50; //这个返回值,由AsyncTask<Integer, Integer, Integer>的第三个类型决定
}
@Override
protected void onProgressUpdate(Integer... values) {//类型由AsyncTask<Integer, Integer, Integer>的第三参数决定
super.onProgressUpdate(values);
//值是由publishProgress();传递进来的
Log.d("tag","values::"+values);
dialog.setMax(values[0]);
dialog.setProgress(values[1]);
}
@Override
protected void onPostExecute(Integer result) {//类型由AsyncTask<Integer, Integer, Integer>的第三参数决定
//参数是从doInbackground的返回值传递过来的
super.onPostExecute(result);
dialog.dismiss();
Toast.makeText(MainActivity.this, "任务结束了", 0).show();
Log.d("tag",result+":::");
}
}
}
注意事项:
- Asynctask的执行必须发生在主线程
- 请不要直接调用以上4个方法
- 任务一旦执行之后,就不能再执行第二次了,除非又重新new了一次task
- 如何取消: t.cancel(true);
- 从1.6的时候,可以并发多个任务,但是从3.0之后,只能执行单个任务。如果想执行多个任务,那么可以使用 t.executeOnExecutor(exec, params) , 使用指定的线程池来运行任务。