AsyncTask是Android为了简化异步操作而封装的异步任务操作抽象类。当我们需要在程序中执行耗时的异步操作时,我们可以考虑使用AsyncTask来实现。

那么Android中为什么需要异步任务操作呢?

★Android是单线程模型

★Android中UI主线程不能进行耗时操作,否则可能报ANR异常。

使用AsyncTask比较简单,因为它是抽象类,我们通常会写一个类来继承AsyncTask<Params,Progress,Result>,继承AsyncTask需要指定三个泛型参数,参数分别表示为:

★Params:启动任务时输入的参数类型,比如我们输入的String类型url
★Progress:后台任务执行中返回的进度值类型,通常来更新ui进度
★Result:耗时操作完成后返回的结果。
同时实现AsyncTask类还需要重写相应的回调方法,一般我们用到的有如下四个方法:
★doInBackground(Void... params):必须重写,异步执行耗时操作
★onPreExecute():执行耗时操作前被调用,通常用来完成一些初始化操作
★onProgressUpdate(Void... values):将doInBackground方法返回的值传递给该方法,在doInBackground中调用publishProgroess()方法可以且来更新进度

★onPostExecute(Void result):耗时的异步任务完成后回调该方法

下面开始学习内容:


首先我们看下AsyncTask执行耗时操作时对应方法的执行顺序):


这样我们可以很明显看出相应方法的执行顺序。

接下来我们看加载图片,还是截图:


第三个小点模拟进度显示就是在Actitivty上显示一个不断加载的进度条,就不贴图啦。

下面是上面三个小点的代码----->主界面代码(对应布局就是三个Button)

public class MainActivity extends Activity implements OnClickListener {
private Button circleBtn, picBtn, progressBtn;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intViews();
initListeners();
}

private void intViews() {
this.circleBtn = (Button) findViewById(R.id.circle_btn);
this.picBtn = (Button) findViewById(R.id.load_pic_btn);
this.progressBtn = (Button) findViewById(R.id.progress_btn);
}

private void initListeners() {
this.circleBtn.setOnClickListener(this);
this.picBtn.setOnClickListener(this);
this.progressBtn.setOnClickListener(this);
}

@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.circle_btn:
startActivity(new Intent(MainActivity.this, LifeCircleActivity.class));
break;
case R.id.load_pic_btn:
startActivity(new Intent(MainActivity.this, LoadImageActivity.class));
break;
case R.id.progress_btn:
startActivity(new Intent(MainActivity.this, ProgressActivity.class));
break;
}
}
}

---------->查看AsyncTask执行方法顺序代码(对应布局空页面:

public class LifeCircleActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_kongbai);
new CircleAsynctask().execute();
}

class CircleAsynctask extends AsyncTask<Void, Void, Void> {
/* 实现AsyncTask必须实现的方法:异步执行后台线程将要完成耗时操作* */
@Override
protected Void doInBackground(Void... params) {
publishProgress();
Log.e("ldm", "doInBackground");
return null;
}
/* 实现AsyncTask必须实现的方法:异步执行后台线程将要完成耗时操作* */
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
Log.e("ldm", "onPostExecute");
}
/* 执行后台耗时操作前被调用,通常用户完成一些初始化操作* */
@Override
protected void onPreExecute() {
super.onPreExecute();
Log.e("ldm", "onPreExecute");
}
/* 将doInBackground方法返回的值传递到该方法,并可以更新主线程ui* */
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
Log.e("ldm", "onProgressUpdate");
}
}
}

---------->异步加载网络图片代码(对应布局就是Button+ImageView):

public class LoadImageActivity extends Activity {
private ImageView mImageView;
private ProgressBar mProgressBar;
private Button mButton;
private static final String IMAGE_URL = "http://pic.qiantucdn.com/58pic/16/85/34/72K58PICjMU_1024.jpg";


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_load_image);
intViewsAndEvents();
}


private void intViewsAndEvents() {
this.mImageView = (ImageView) findViewById(R.id.load_image);
this.mProgressBar = (ProgressBar) findViewById(R.id.load_bar);
this.mButton = (Button) findViewById(R.id.load_pic_btn);
this.mButton.setOnClickListener(new OnClickListener() {


@Override
public void onClick(View v) {
new LoadImageAsynctask().execute(IMAGE_URL);
}
});
}


class LoadImageAsynctask extends AsyncTask<String, Void, Bitmap> {


/* 实现AsyncTask必须实现的方法:异步执行后台线程将要完成耗时操作* */
@Override
protected Bitmap doInBackground(String... params) {
String url = params[0];// 获取传递进来的参数
Bitmap bitmap = null;
URLConnection conn = null;
InputStream in;
try {
conn = new URL(url).openConnection();
in = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(in);
// 通过BitmapFactory.decodeStream()方法解析输入流
bitmap = BitmapFactory.decodeStream(bis);
in.close();
bis.close();
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return bitmap;// 返回Bitmap
}


/* 实现AsyncTask必须实现的方法:异步执行后台线程将要完成耗时操作* */
@Override
protected void onPostExecute(Bitmap result) {
mProgressBar.setVisibility(View.GONE);
mImageView.setImageBitmap(result);// 加载完成显示图片
}


/* 执行后台耗时操作前被调用,通常用户完成一些初始化操作* */
@Override
protected void onPreExecute() {
super.onPreExecute();
mProgressBar.setVisibility(View.VISIBLE);// 后台执行前显示加载框
}


/* 将doInBackground方法返回的值传递到该方法,并可以更新主线程ui* */
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}


}
}

--------->模拟进度条进度代码(对应布局仅仅一个ProgressBar):

public class ProgressActivity extends Activity {
private ProgressBar mProgressBar;
private ProgressAsynctask mAsyncTask;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_progress);
this.mProgressBar = (ProgressBar) findViewById(R.id.mpbar);
mAsyncTask = new ProgressAsynctask();
mAsyncTask.execute();
}

@Override
protected void onPause() {
super.onPause();
if (mAsyncTask != null && mAsyncTask.getStatus() == AsyncTask.Status.RUNNING) {// 判断当前异步任务是否在进行中
// cancel()方法只是将对应的AsyncTask状态标记为cancel状态,并没有真正取消异步操作
mAsyncTask.cancel(true);
}
}

class ProgressAsynctask extends AsyncTask<Void, Integer, Void> {
/* 实现AsyncTask必须实现的方法:异步执行后台线程将要完成耗时操作* */
@Override
protected Void doInBackground(Void... params) {
for (int i = 0; i < 100; i++) {
if (isCancelled()) {// 如果异步任务取消,则跳出循环
break;
}
publishProgress(i);
try {
Thread.sleep(100);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}

/* 实现AsyncTask必须实现的方法:异步执行后台线程将要完成耗时操作* */
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
}


/* 执行后台耗时操作前被调用,通常用户完成一些初始化操作* */
@Override
protected void onPreExecute() {
super.onPreExecute();
}


/* 将doInBackground方法返回的值传递到该方法,并可以更新主线程ui* */
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
if (isCancelled()) {// 如果异步任务取消,则跳出循环
return;
}
mProgressBar.setProgress(values[0]);// 进度条数值显示
}
}
}

最后总结下使用AsyncTask执行异步操作注意事项:
★ AsyncTask的实例(子类)必须在UI主线程中创建
★ AsyncTask的execute()方法也必须在UI主线程中调用
★重写的四个方法是系统自动调用,不能手动更改
★每个AsyncTask只能被同时执行一次,多次调用将导致异常

更多相关文章

  1. 浅谈Java中Collections.sort对List排序的两种方法
  2. Python list sort方法的具体使用
  3. python list.sort()根据多个关键字排序的方法实现
  4. Android通讯录数据库介绍与基本操作(增删改查)
  5. Android应用AsyncTask处理机制详解及源码分析
  6. Android(安卓)Activity生命周期具体内容概述
  7. [Android]LayoutInflater的inflate方法半详解
  8. 【Android自助餐】Handler消息机制完全解析(一)Message中obtain()
  9. Android与Unity交互调用mUnityPlayer.quit()方法退出返回上一个A

随机推荐

  1. AS 配置使用NDK
  2. Android之监测database的改变--notifyCha
  3. Android(安卓)-- 自定义View
  4. Android(安卓)view 滑动事件冲突解决方法
  5. Android(安卓)Fragment 体系源码跟踪笔记
  6. 使用 Intel HAXM 为 Android(安卓)模拟器
  7. Android(安卓)右滑关闭当前Activity(类微
  8. 9.5android线程优先级,go和rust比较
  9. Android(安卓)Handler 避免内存泄漏的用
  10. Android(安卓)线程 Looper.prepare()、Lo