文章目录
- 1、简介
- 2、示例模板
- 3、实例讲解
- 1) AsncTask 生命周期
- 2) 内存泄漏 静态内部类 + 弱引用
- 3)多个AsyncTask 实例 同步还是异步进行
- 4)线程任务执行结果 丢失
- 5)优缺点
1、简介
作用同 Thread + handler 类似,用于开启线程做一些耗时操作,同时有接口实现ui更新。
但是效率,比我们自己使用thread + handler 要高。Aysnctsk,内部封装了一个线程池,用来执行线程操作。一个进程中 AsyncTask 对象公用同一个线程池。
2、示例模板
我们模拟 网络下载 ,同时更新下载进度的 ,下载完成通知这一个基本框架。
主功能代码:
package myapplication.lum.com.myasynctask;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private String TAG = "MainActivity: ";
private TextView tv_text;
private Button button;
MyAsyncTask task ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_text = (TextView) findViewById(R.id.tv_text_id);
button = (Button) findViewById(R.id.bt_id);
task = new MyAsyncTask();
}
public void onClick(View view) {
switch (view.getId()){
case R.id.bt_id:
//执行
task.execute("www.baidu.com");
Log.i(TAG,"点击下载");
break;
case R.id.bt_can_id:
task.cancel(true);
Log.i(TAG,"取消按钮");
break;
}
}
class MyAsyncTask extends AsyncTask<String,Integer, String> {
/**
* 被主线程执行,在doInBackground函数前执行
* */
@Override
protected void onPreExecute() {
// 弹加载对话框
Log.d(TAG, "onPreExecute ");
}
/**
* 被子线程执行,用来处理耗时行为
* */
@Override
protected String doInBackground(String... params) {
Log.d(TAG, "doInBackground: "+ params[0]);
for(int i=1;i<=10;i++){
try {
Thread.sleep(1000);
//推送当前的进度
publishProgress(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "下载完成";
}
@Override
protected void onProgressUpdate(Integer... values) {
//更新UI上的进度
tv_text.setText(values[0]+"");
}
/**
* 被主线程执行,在doInBackground函数后执行
* */
@Override
protected void onPostExecute(String result) {
Log.d(TAG, "onPostExecute");
// 更UI数据
tv_text.setText(result);
}
// onCancelled()
// 作用:将异步任务设置为:取消状态
@Override
protected void onCancelled() {
Log.i(TAG,"onCancelled task");
tv_text.setText("下载已经取消");
}
}
}
3、实例讲解
1) AsncTask 生命周期
AsncTask 不与任何组件绑定生命周期,在Activity 、Fragment中使用的时候,最好在 onDestory() 中主动调用 myTask.cancel(true);
2) 内存泄漏 静态内部类 + 弱引用
若 AsyncTask 被声明为 Activity的非静态内部类,当activity需销毁的时候,会因为AsyncTask 保留对Activity的引用而导致Activity无法被回收,最终引起内存泄漏。建议 AsyncTask应被声明为Activity的静态内部类。
采用弱引用示例
package myapplication.lum.com.myasynctask;
import android.app.Activity;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.lang.ref.WeakReference;
public class MainActivity extends AppCompatActivity {
private String TAG = "MainActivity: ";
private TextView tv_text;
private Button button;
MyAsyncTask task ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_text = (TextView) findViewById(R.id.tv_text_id);
button = (Button) findViewById(R.id.bt_id);
task = new MyAsyncTask(this);
}
public void onClick(View view) {
switch (view.getId()){
case R.id.bt_id:
//执行
task.execute("www.baidu.com");
Log.i(TAG,"点击下载");
break;
case R.id.bt_can_id:
task.cancel(true);
Log.i(TAG,"取消按钮");
break;
}
}
static class MyAsyncTask extends AsyncTask<String,Integer, String> {
private WeakReference<Activity> weakAty;
private String TAG = "MyAsyncTask: ";
public MyAsyncTask(Activity activity){
weakAty = new WeakReference<Activity>(activity);
}
/**
* 被主线程执行,在doInBackground函数前执行
* */
@Override
protected void onPreExecute() {
// 弹加载对话框
Log.d(TAG, "onPreExecute ");
}
/**
* 被子线程执行,用来处理耗时行为
* */
@Override
protected String doInBackground(String... params) {
Log.d(TAG, "doInBackground: "+ params[0]);
for(int i=1;i<=10;i++){
try {
Thread.sleep(1000);
//推送当前的进度
publishProgress(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "下载完成";
}
// onCancelled()
// 作用:将异步任务设置为:取消状态
@Override
protected void onCancelled() {
Log.i(TAG,"onCancelled task");
MainActivity mainActivity ;
if((mainActivity = (MainActivity) weakAty.get())!=null){
// 更UI数据
mainActivity.tv_text.setText("下载已经取消");
}
}
@Override
protected void onProgressUpdate(Integer... values) {
//更新UI上的进度
MainActivity mainActivity ;
if((mainActivity = (MainActivity) weakAty.get())!=null){
// 更UI数据
mainActivity.tv_text.setText(values[0]+"");
}
}
/**
* 被主线程执行,在doInBackground函数后执行
* */
@Override
protected void onPostExecute(String result) {
Log.d(TAG, "onPostExecute");
MainActivity mainActivity ;
if((mainActivity = (MainActivity) weakAty.get())!=null){
// 更UI数据
mainActivity.tv_text.setText(result);
}
}
}
}
3)多个AsyncTask 实例 同步还是异步进行
两个实例
task_one
task_two
(1)
task_one.execute(urls);//第一个实例执行
task_two.execute(urls);//第二个实例执行
这种执行方法 ,那么 task_one ,task_two 是同步执行的,会在线程先执行 task_one ,然后结束后再执行 task_two
(2)
task_one.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,urls);//第一个实例执行
task_two.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,urls);//第二个实例执行
第一个参数是一个Executor线程池对象,为了让AsyncTask并行处理任务。通常情况下我们此处传入AsyncTask.THREAD_POOL_EXECUTOR即可。
第二个参数params表示的是要执行的任务的参数。
这种方法是同时开启两个线程并行执行的。
4)线程任务执行结果 丢失
当Activity重新创建时(屏幕旋转 / Activity被意外销毁时后恢复),之前运行的AsyncTask(非静态的内部类)持有的之前Activity引用已无效,故复写的onPostExecute()将不生效,即无法更新UI操作。
在Activity恢复时的对应方法 重启 任务线程。
5)优缺点
优点:
简单,快捷
过程可控
使用的缺点:
对只需要几秒内的线程操作方便
缺点:
在使用多个异步操作和并需要进行Ui变更时,就变得复杂起来.