AsyncTask. 异步任务
- **目的:方便后台线程中操作后
更新UI
- **目的:方便后台线程中操作后
封装并简化了异步操作
**
- 实现:`Thread`和`Handler`进行了封装
- 实质:`Handler`异步消息处理机制
- 参数是泛型:`<Params,Progress,Result>`
- UI操作:`onPreExecute`,`onPostExecute`
- 后台线程操作 `doInBackground`
- 输入输出:`Params`(入),`Result`(出)
- 进度显示:`onProgressUpdate`
ANR(Application Not Responding)
- 应用程序无响应,
**原因:UI线程被耗时任务(网络请求、下载上传、加载图片等)阻塞,界面卡死;
所以,
注意适当开启异步任务、子线程;
处理耗时操作,防止UI线程出现ANR现象**
- UI线程做主线程,
子线程做工作线程;
- 如果在子线程更新UI更新主线程的东西,
app会闪退,崩溃,
保证线程安全;
子线程可以通过以下几个方法,
切换到主线程更新:
- `Activity.runOnUiThread(Runnable)`
- `View.post(Runnable)`
- `View.postDelayed(Runnable,long)`
AsyncTask解析
- **查看AsyncTask源码:
可以在项目的任意位置,Ctrl+N,打开输入框,输入想要查看的类名,
点击搜索到的类名,即可前往查看源码:**
- **可以看到首先AsyncTask它是个抽象类,
参数都是泛型:**
使用
- **使用时首先需要新建一个类,
继承
自AsyncTask
,
泛型
要填包装类
,或者自定义的Model类型
,
系统要求至少一定要继承doInBackground()
这个方法,
即在后台子线程
进行的一个方法,doInBackground()
的参数类型
,
即泛型的第一个参数类型
,即入参Params
的参数类型
,
return 返回的是结果,即泛型的第三个参数:**
public class DownloadAsyncTask extends AsyncTask<String, Integer, Boolean> {
@Override
protected Boolean doInBackground(String... strings) {
return null;
}
}
- **
String...
中的三个点,
表示该参数的长度是可变的;**
- **写完定义类之后,
在主线程new
一下即可,
使用execute()
,传入可变长度的入参,
即可启动AsyncTask
:**
public class MainActivity extends AppCompatActivity {
//logt 然后回车,快速生成!!!!!!!!
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new DownloadAsyncTask().execute("哈喽", "早上好");
}
public class DownloadAsyncTask extends AsyncTask<String, Integer, Boolean> {
/**
* 方法执行在异步任务之前,执行在主线程中!!
* 方法体中,可以 ;‘’;操作UI !!
*/
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Boolean doInBackground(String... params) {
// fori 回车 快速生成!!!!!!!!!!!
for (int i = 0; i < 10000; i++) {
Log.i(TAG, "doInBackground " + i +
": " + params[0] + "," + params[1]);
}
return true;
}
}
}
运行:
各方法作用概述,如代码中注释:
public class MainActivity extends AppCompatActivity {
//logt 然后回车,快速生成!!!!!!!!
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new DownloadAsyncTask().execute("哈喽", "早上好");
}
public class DownloadAsyncTask extends AsyncTask<String, Integer, Boolean> {
/**
* 方法执行在异步任务之前,执行在主线程中!!
* 方法体中,可以 ;‘’;操作UI !!
*/
@Override
protected void onPreExecute() {
super.onPreExecute();
}
/**
* 本方法运行在子线程中,
* 处理工作内容、耗时操作
*
* @param params
* @return
*/
@Override
protected Boolean doInBackground(String... params) {
// fori 回车 快速生成!!!!!!!!!!!
for (int i = 0; i < 10000; i++) {
Log.i(TAG, "doInBackground " + i +
": " + params[0] + "," + params[1]);
publishProgress(i);//抛出进度
}
return true;
}
/**
* 本方法运行在主线程中,可以处理结果
* 当任务执行完了,即doInBackground()一旦return,
* 其return的值就会传到这里,作为参数,
* 参数类型即定义泛型时的第三个参数
* @param aBoolean
*/
@Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
}
/**
* 本方法运行在主线程
* 进度变化就在这个方法处理
* 接收来自 doInBackground()中 publishProgress()抛出的进度,
* 并处理
*
* @param values 类型是定义时的第二个泛型参数,
* 数据来自 doInBackground()的 publishProgress()
*/
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
}
}
补充
onCancelled()
:- 运行在:主线程
调用时刻:当异步任务被取消时被调用
作用:可用于做界面取消的更新
- 注意:
不要直接调用onPreExecute()
、doInBackground()
、onProgressUpdate()
、onPostExecute()
和onCancelled()
方法
AsyncTask对象必须在主线程创建;
- 开始和结束异步任务的方法:
execute(Params...params)
必须在主线程
中调用,参数
为泛型定义的第一参
,即入参
!
作用:表示开始一个异步任务
注意:一个异步对象只能调用一次execute()方法
cancel(booleanmayInterruptIfRunning)
必须在主线程
中调用
作用:表示停止一个异步任务