Android——AsyncTask

一.什么是AsyncTask?

 

Android中,如果想要在子线程里进行UI操作,就需要借助异步消息处理机制,在Android中实现异步任务机制有两种方式,Handler和AsyncTask。Handler在上一篇文章已简单讲述,这里讲述AsyncTask的使用。AsyncTask相对于Handle,代码较为简单,使用更便捷,也可以准确控制子线程。

AsyncTask使用步骤:

 

  1. 新建内部类继承AsyncTask;
  2. 定义AsyncTask的三种泛型参数;
  3. 重写doInBackground抽象方法;
  4. 重写onPreExecute抽象方法;
  5. 重写onProgressUpdate方法;
  6. 重写onPostEcecute方法;
  7. 在需要启动的地方调用execute方法。

 

 

有三个泛型参数: 

 

class DownloadTask extends AsyncTask<Integer, Integer, String>
三种泛型类型分别代表“启动任务执行的输入参数”、“后台任务执行的进度”、“后台计算结果的类型“。 
AsyncTask执行步骤: 
1.execute(Params… params),调用此方法,启动子线程。execute方法必须在UI线程中调用,同时启动多个任务时,将按照先后顺序逐一执行

比较:executeOnExecutor必须在UI线程中调用,使用executeOnExecutor方法可以并行执行多个任务,但最多也只能是5个任务同时执行

2.onPreExecute(),在execute(Params… params)被调用后立即执行,此方法运行在主线程中,可对控件进行初始化设置,当然这个方法可省略。

3.doInBackground(Params… params),在onPreExecute()完成后立即执行,此方法运行在子线程中,执行费时操作,可以接收输入参数和返回计算结果。注意,这个方法不可以省略

4.onProgressUpdate(Progress… values),在调用publishProgress(Progress… values)时,此方法被执行,直接将进度信息更新到UI组件。

5.onPostExecute(Result result),当后台操作结束时,此方法将会被调用,计算结果将做为参数传递到此方法中,直接将结果显示到UI组件上

 

二.如何使用AsyncTask

 

带进度AsyncTask方法调用步骤:

1.定义AsyncTask

 

class MyTask extends AsyncTask<Integer,Integer,String>

2.在UI线程中启动AsyncTask

 

new MyTask().execute()
3.可初始化控件

 

protected void onPreExecute() {
}
4.执行耗时操作

 

protected String doInBackground(Integer... integers) {
    return null;
}
5.根据String设置控件

 

protected void onPostExecute(String s) {
}

不带进度AsyncTask方法调用步骤:

 

1.定义AsyncTask

class MyTask extends AsyncTask<Integer,Integer,String>

2.在UI线程中启动AsyncTask

new MyTask().execute()

3.可初始化控件

protected void onPreExecute() {
}

4.执行耗时操作

protected String doInBackground(Integer... integers) {
    return null;
}

5.得到进度设置控件进度

 

protected void onProgressUpdate(Integer... values) {
}

6.根据Result设置控件

protected void onPostExecute(String s) {
}

三.使用AsyncTask做倒计时

  1.xml布局简单,附上代码:

 

 
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

  2. android:layout_width="match_parent"

  3. android:layout_height="match_parent"

  4. android:orientation="vertical">

  5.  
  6. <EditText

  7. android:id="@+id/daojishi_ed"

  8. android:layout_width="match_parent"

  9. android:layout_height="50dp" />

  10.  
  11. <TextView

  12. android:id="@+id/daojishi_tv"

  13. android:layout_width="match_parent"

  14. android:layout_height="50dp"

  15. android:text="0"

  16. android:textSize="30sp"

  17. android:gravity="center"/>

  18.  
  19. <Button

  20. android:id="@+id/daojishi_btn"

  21. android:layout_width="match_parent"

  22. android:layout_height="50dp"

  23. android:text="开始倒计时"/>

  24.  
  25. </LinearLayout>

还有xml预览图

 

2.首先贴上完整的Java代码,下面再进行具体描述:

 

 
  1. public class ASdaojishiActivity extends AppCompatActivity {

  2. private TextView daojishiTV;

  3. private Button daojishiBtn;

  4. private EditText daojishiEdit;

  5. int time;

  6.  
  7. @Override

  8. protected void onCreate(Bundle savedInstanceState) {

  9. super.onCreate(savedInstanceState);

  10. setContentView(R.layout.activity_asdaojishi);

  11.  
  12. bindID();

  13.  
  14. daojishiBtn.setOnClickListener(new View.OnClickListener() {

  15. @Override

  16. public void onClick(View view) {

  17. time = Integer.parseInt(daojishiEdit.getText().toString());

  18. daojishiBtn.setText("正在倒计时");

  19. new MyAsyncTask().execute(time);

  20. }

  21. });

  22.  
  23. }

  24.  
  25. private void bindID() {

  26. daojishiTV = findViewById(R.id.daojishi_tv);

  27. daojishiBtn = findViewById(R.id.daojishi_btn);

  28. daojishiEdit = findViewById(R.id.daojishi_ed);

  29. }

  30.  
  31. class MyAsyncTask extends AsyncTask<Integer,Integer,String>{

  32.  
  33. @Override

  34. protected String doInBackground(Integer... integers) {

  35. for (int i = integers[0]; i >= 0; i--){

  36. try {

  37. Thread.sleep(1000);

  38. publishProgress(i);

  39. } catch (InterruptedException e) {

  40. e.printStackTrace();

  41. }

  42. }

  43. return "倒计时结束";

  44. }

  45.  
  46. @Override

  47. protected void onProgressUpdate(Integer... values) {

  48. super.onProgressUpdate(values);

  49. daojishiTV.setText(values[0]+"");

  50. }

  51.  
  52. @Override

  53. protected void onPostExecute(String s) {

  54. super.onPostExecute(s);

  55. daojishiBtn.setText(s);

  56. }

  57. }

  58.  
  59. }

3.首先需要一个内部类

 

 

class MyAsyncTask extends AsyncTask<Integer,Integer,String>

 

doInBackground方法必不可少,在其内部执行耗时操作

 

 
  1. @Override

  2. protected String doInBackground(Integer... integers) {

  3. for (int i = integers[0]; i >= 0; i--){

  4. try {

  5. Thread.sleep(1000);

  6. publishProgress(i);

  7. } catch (InterruptedException e) {

  8. e.printStackTrace();

  9. }

  10. }

  11. return "倒计时结束";

  12. }

这里还需要用到两种方法,onProgressUpdate和onPostExecute

 

 

 
  1. @Override

  2. protected void onProgressUpdate(Integer... values) {

  3. super.onProgressUpdate(values);

  4. daojishiTV.setText(values[0]+"");

  5. }

  6.  
  7. @Override

  8. protected void onPostExecute(String s) {

  9. super.onPostExecute(s);

  10. daojishiBtn.setText(s);

  11. }

当然,启动AsyncTask不能缺少

new MyAsyncTask().execute(time);
publishProgress(i);//此行代码对应下面onProgressUpdate方法
return "倒计时结束";//return的String类型数值,给到onPostExecute内的参数

四.使用AsyncTask做进度条

 

 

 

1.xml布局简单,附上代码:

 

 
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

  2. android:layout_width="match_parent"

  3. android:layout_height="match_parent"

  4. android:orientation="vertical">

  5.  
  6. <ProgressBar

  7. android:id="@+id/jindutiao_bar"

  8. android:layout_width="match_parent"

  9. android:layout_height="50dp"

  10. style="@style/Widget.AppCompat.ProgressBar.Horizontal"/>

  11.  
  12. <Button

  13. android:id="@+id/download_btn"

  14. android:layout_width="match_parent"

  15. android:layout_height="50dp"

  16. android:text="点击下载"/>

  17.  
  18. </LinearLayout>

还有xml预览图

2.首先贴上完整的Java代码,下面再进行具体描述:

 

 
  1. public class ASjindutiaoActivity extends AppCompatActivity {

  2.  
  3. private ProgressBar Bar;

  4. private Button downloadBtn;

  5.  
  6. @Override

  7. protected void onCreate(Bundle savedInstanceState) {

  8. super.onCreate(savedInstanceState);

  9. setContentView(R.layout.activity_asjindutiao);

  10.  
  11. bindID();

  12.  
  13. downloadBtn.setOnClickListener(new View.OnClickListener() {

  14. @Override

  15. public void onClick(View view) {

  16. downloadBtn.setText("正在下载");

  17. new MyTask().execute();

  18. }

  19. });

  20.  
  21. }

  22.  
  23. private void bindID() {

  24. Bar = findViewById(R.id.jindutiao_bar);

  25. downloadBtn = findViewById(R.id.download_btn);

  26.  
  27. Bar.setMax(5);

  28.  
  29. }

  30.  
  31. class MyTask extends AsyncTask<Integer,Integer,String>{

  32.  
  33. @Override

  34. protected String doInBackground(Integer... integers) {

  35.  
  36. for (int i = 1;i <= 5;i++){

  37. try {

  38. Thread.sleep(1000);

  39. publishProgress(i);

  40. } catch (InterruptedException e) {

  41. e.printStackTrace();

  42. }

  43. }

  44. return "下载完成";

  45. }

  46.  
  47. @Override

  48. protected void onProgressUpdate(Integer... values) {

  49. super.onProgressUpdate(values);

  50. Bar.setProgress(values[0]);

  51. }

  52.  
  53. @Override

  54. protected void onPostExecute(String s) {

  55. super.onPostExecute(s);

  56. downloadBtn.setText(s);

  57. }

  58. }

  59.  
  60. }

3.首先需要一个内部类
class MyTask extends AsyncTask<Integer,Integer,String>
doInBackground方法必不可少,在其内部执行耗时操作
 
  1. @Override

  2. protected String doInBackground(Integer... integers) {

  3.  
  4. for (int i = 1;i <= 5;i++){

  5. try {

  6. Thread.sleep(1000);

  7. publishProgress(i);

  8. } catch (InterruptedException e) {

  9. e.printStackTrace();

  10. }

  11. }

  12. return "下载完成";

  13. }

这里还需要用到两种方法,onProgressUpdate和onPostExecute
 
  1. @Override

  2. protected void onProgressUpdate(Integer... values) {

  3. super.onProgressUpdate(values);

  4. Bar.setProgress(values[0]);

  5. }

  6.  
  7. @Override

  8. protected void onPostExecute(String s) {

  9. super.onPostExecute(s);

  10. downloadBtn.setText(s);

  11. }

  12. }

当然,启动AsyncTask不能缺少
 new MyTask().execute();

 

publishProgress(i);//此行代码对应下面onProgressUpdate方法
return "倒计时结束";//return的String类型数值,给到onPostExecute内的参数

五.Execute()和executeOnExecutor有何区别

 

 

Execute():这个函数让任务是以单线程队列方式或线程池队列方式运行,会让任务以后台单线程串行方式执行。

 

 

executeOnExecutor():这个方法通常和THREAD_POOL_EXECUTOR一起使用,允许多个任务在由AsyncTask管理的线程池中并行执行。

 

AsyncTask实现的原理和适用的优缺点

AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程.

使用的优点:

简单,快捷

过程可控      

使用的缺点:

在使用多个异步操作和并需要进行Ui变更时,就变得复杂起来.

 

Handler异步实现的原理和适用的优缺点

在Handler 异步实现时,涉及到 Handler, Looper, Message,Thread四个对象,实现异步的流程是主线程启动Thread(子线程)运行并生成Message-Looper获取Message并传递给HandlerHandler逐个获取Looper中的Message,并进行UI变更。

使用的优点:

结构清晰,功能定义明确

对于多个后台任务时,简单,清晰

使用的缺点:

 在单个后台异步处理时,显得代码过多,结构过于复杂(相对性)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值