·AsyncTask是一个轻量级的异步抽象类
·Android程序刚启动时,会同时启动一个像一个的主线程,这个主线程主要负责处理与UI有关的事件,有时也被称为UI线程,Android app中必须遵循单线程模型原则:Android UI操作并不是线程安全的并且这些操作都要在ui线程中进行假如我们在非UI线程中,比如在主线程中new Thread()另外开辟一个线程,然后直接在里面修改UI控件的值; 此时会抛出下述异常:android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views 另外,还有一点,如果我们把耗时的操作都放在UI线程中的话,如果UI线程超过5s没有响应用于请求,那么 这个时候会引发ANR(Application Not Responding)异常,就是应用无响应~ 最后还有一点就是:Android 4.0后禁止在UI线程中执行网络操作~不然会报: android.os.NetworkOnMainThreadException
·相关参数:
AsyncTask<Params,Progress,Result>
Params:启动任务执行的输入参数
Progress:后台任务的百分比
Result:后台任务执行的结果,String,Integer等
·相关方法与流程:
execute(Param):在主线程中手动调用触发异步线程任务
onPreExrcute():执行后台耗时操作前调用,通常用于初始化操作,比如进度条的显示。
doInBackground(Param):在onPreExecute后立即执行,负责执行后台耗时操作,可调用publishProgress(Progress)更新任务进度。
onPostExecute(Result):在doInBackground执行完成后,onPostExecute方法将被ui线程调用,后台计算结果通过该方法传递到ui线程展示给用户。
OnProgressUpdate(Progress):在publishProgress方法被调用后,ui线程调用此方法在界面上展示任务进度情况。
onCnacelled():用户取消线程时调用。
·在Activity或Fragment中使用AsyncTask时,最好在Activity或Fragment的onDestory()调用cancel(boolean);
· 当Activity重新创建时(屏幕旋转 / Activity被意外销毁时后恢复),之前运行的AsyncTask(非静态的内部类)持有的之前Activity引用已无效,故复写的onPostExecute()将不生效,即无法更新UI操作
使用建议
在Activity恢复时的对应方法 重启 任务线程
· 若AsyncTask被声明为Activity的非静态内部类,当Activity需销毁时,会因AsyncTask保留对Activity的引用 而导致Activity无法被回收,最终引起内存泄露
使用建议
AsyncTask应被声明为Activity的静态内部类
代码示例:
1 package com.deep.myapplication5.AsyncTask; 2 3 import androidx.appcompat.app.AppCompatActivity; 4 5 import android.os.AsyncTask; 6 import android.os.Bundle; 7 import android.view.View; 8 import android.widget.Button; 9 import android.widget.ProgressBar; 10 11 import com.example.myapplication5.R; 12 13 import static java.lang.Thread.sleep; 14 15 public class AsyncTaskActivity extends AppCompatActivity { 16 private Button button; 17 private ProgressBar progressBar; 18 private boolean sentence=true; 19 @Override 20 protected void onCreate(Bundle savedInstanceState) { 21 super.onCreate(savedInstanceState); 22 setContentView(R.layout.activity_async_task); 23 button=findViewById(R.id.async_btn); 24 progressBar=findViewById(R.id.async_progress); 25 final mAsyncTask mAsyncTask1 = new mAsyncTask(); 26 button.setOnClickListener(new View.OnClickListener() { 27 @Override 28 public void onClick(View v) { 29 if (sentence){ 30 mAsyncTask1.execute(); 31 sentence=false; 32 } 33 else{ 34 mAsyncTask1.cancel(true); 35 36 sentence=true; 37 } 38 } 39 }); 40 } 41 42 public class mAsyncTask extends AsyncTask<String,Integer,String>{ 43 44 @Override 45 protected void onPreExecute() { 46 super.onPreExecute(); 47 button.setText("正在加载···"); 48 } 49 50 @Override 51 protected String doInBackground(String... strings) { 52 int count=0; 53 while (count<100){ 54 count++; 55 publishProgress(count); 56 try { 57 sleep(50); 58 } catch (InterruptedException e) { 59 e.printStackTrace(); 60 } 61 } 62 return null; 63 } 64 65 @Override 66 protected void onProgressUpdate(Integer... values) { 67 super.onProgressUpdate(values); 68 progressBar.setProgress(values[0]); 69 button.setText("已加载"+values[0]+"%"); 70 } 71 72 @Override 73 protected void onPostExecute(String s) { 74 super.onPostExecute(s); 75 button.setText("加载完毕!"); 76 } 77 78 @Override 79 protected void onCancelled() { 80 super.onCancelled(); 81 button.setText("已取消!"); 82 progressBar.setProgress(0); 83 } 84 } 85 86 }
参考:https://www.jianshu.com/p/ee1342fcf5e7
https://www.runoob.com/w3cnote/android-tutorial-ansynctask.html