【Android基础】AsyncTask基础

Android单线程模型

当一个程序第一次启动时,Android会同时启动一个主线程(Main Thread),主线程主要负责处理与UI相关的事件,如:用户的按键事件,用户点击按钮的事件,用户接触屏幕的事件以及屏幕绘图事件等,同时,主线程会把相关的事件分发到对应的组件进行处理。所以主线程通常又叫做UI线程。
在开发Android 应用时必须遵守单线程模型的原则:
Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行。
在非UI线程(子线程)中不可以直接操作UI线程,即不可以设定UI,否则会抛出:android.view.ViewRoot$CalledFromWrongThreadException异常。
单线程模型优点:
1. 保证UI的准确性
2. 保证UI的稳定性,避免多线程同时对UI操作而造成的混乱

AsyncTask概述

Android虽然是单线程模型,但这个单线程只限于UI。另外的一些耗时操作,如网络连接、读取文件等都可以放在子线程中进行。但多线程编程实现又较为繁琐,所以,Android提供了一个封装良好的组件——AsyncTask。
AsyncTask是Android中进行异步任务的组件,其诞生的目的是:
- 实现子线程中更新UI
- 封装、简化异步任务

AsyncTask基本结构

AsyncTask<Params,Progress,Result>是抽象类,使用时需被继承,下面介绍其基本结构。

继承时需指定的三个泛型参数

  • Params:启动任务时输入参数的类型
  • Progress:后台任务执行中返回进度值的类型
  • Result:后台执行任务完成后返回结果的类型
    所以,这三个参数都是数据类型,也就是所谓的泛型参数。
    例:
public class AsyncTaskTest extends AsyncTask<Void,Void,Void>{
    @Override
    protected Void doInBackground(Void... params) {
        // TODO Auto-generated method stub
        return null;
    }
}

上例中AsyncTask三个泛型参数都为Void。

需重写的回调方法

  • doInBackground:必须重写的方法,里面是后台执行线程将要完成的任务
  • onPreExecute:在UI线程中运行,运行在后台执行线程之前,用于一些初始化操作
  • onPostExecute:doInBackground方法执行后调用的方法,并且doInBaskground方法返回的值也会传给该方法
  • onProgressUpdate:doInBackground方法执行中调用的方法,用于更新任务的执行进度
    这四个方法可以通过在Eclipse中查看AsyncTask类的源码看到。
    下面是示例:
package com.asynctasktest; 

import android.os.AsyncTask; 

public class AsyncTaskTest extends AsyncTask<Void,Void,Void>{ 

 @Override 
 protected Void doInBackground(Void... params) { 
  // TODO Auto-generated method stub 
  return null; 
 } 

 @Override 
 protected void onPreExecute() { 
 } 

 @Override 
 protected void onPostExecute(Void result) { 
 } 

 @Override 
 protected void onProgressUpdate(Void... values) { 
 } 
} 

doInBackground可以自动生成,另外三个方法就需要自己添加了。

使用AsyncTask

先补充一下上述四个方法里面的执行内容:

package com.asynctasktest;

import android.os.AsyncTask;
import android.util.Log;

public class AsyncTaskTest extends AsyncTask<Void,Void,Void>{

 @Override
 protected Void doInBackground(Void... params) {
  // TODO Auto-generated method stub
  Log.d("AsyncTaskTest","doInBackground");
  //更新进度,执行了此方法方可执行onPregressUpdate
  this.publishProgress();
  return null;
 }

 @Override
 protected void onPreExecute() {
  Log.d("AsyncTaskTest","onPreExecute");
 }

 @Override
 protected void onPostExecute(Void result) {
  Log.d("AsyncTaskTest","onPostExecute");
 }

 @Override
 protected void onProgressUpdate(Void... values) {
  Log.d("AsyncTaskTest","onProgressUpdate");
 }
}

执行的任务只是在Android日志里输出四个方法名。

下面是在主线程中调用AsyncTaskTest,即执行此异步任务:

public class MainActivity extends ActionBarActivity {

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  //实例化AsyncTask
  AsyncTaskTest test = new AsyncTaskTest();
  //启动后台线程
  test.execute();

  //主线程执行任务:在日志中输出Hello,World
  Log.d("MainActivity","Hello, World");
 }

}

执行后在日志中的输出结果为:
【Android基础】AsyncTask基础_第1张图片

最先执行的是onPreExecute,这个方法负责初始化参数,并且是在UI线程中执行,然后就输出了主线程要输出的“Hello, World”,表明AsyncTask的确没阻塞主线程;然后执行了后台任务执行方法doInBackground以及进度更新方法onProgressUpdate方法,最后在doInBackground方法执行后执行了onPostExecute方法,表明后台线程运行结束。

你可能感兴趣的:(android,基础,AsyncTask)