您的位置:首页 > 其它

AsyncTask异步任务类

2016-07-18 20:49 344 查看
AsyncTask异步任务类,比Handle更轻量级,更适合简单的异步操作。内部封装了Handle,在使用AsyncTask类进行刷新控件的刷新操作时,不用再额外创建声明Handle,可以直接使AsyncTask内部封装好的几个方法实现。

一、AsyncTask的实现

使用AsyncTask主要通过实现内部封装的onPreExecute(),doInBackGround(),onProgressSetUpdate(),onPostExecute()等几个方法来进行操作。通过调用.excute()方法开始执行

1、onPreExecute()

onPreExcute()会在后台任务开始之前执行,可以进行一些界面上的初始化操作。

2、doInBackground(Object o)

运行在AsyncTask内部开辟的子线程,一些耗时会阻塞UI的操作都应该放在这个方法内处理,如从网络读取数据、下载任务等,这里的Object o参数,我们可以通过AsyncTask的实例调用.excute(Object o)方法时传入。

3、onProgressSetUpdate()

运行在主线程,也就是UI线程,AsyncTask必须在UI线程声明创建。onProgressSetUpdate(Object o)方法主要是用来显示任务执行的进度,给用户直观的感受。Object o通过publishProgress(Object o)方法传入,因为耗时操作一般是在doInBackGround()方法中执行,所以一般会在doInBackGround()方法中调用pubilshProgress(Object o)传参只onProgressSetUpdate(),然后执行控件的刷新。

4、onPostExecute()

运行在主线程。doInBackground()会有一个返回值,这个返回值会作为参数传入onPostExecute()方法中,可以利用返回的数据进行一些UI操作,进行收尾工作。

二、AsyncTask泛型参数设置

AsyncTask如果不设置泛型参数,那么上面介绍的几个方法参数、返回值都默认为Object,在使用时都必须进行强转,个人感觉很繁琐。我们可以通过设置AsyncTask的泛型参数来解决这个问题。

AsyncTask有三个参数,分别是Params、Progress、Result

1、Params

execute(Params)传入的参数同时也是doInBackGround(Params)方法的参数。

2、Progress

onProgressUpdate(Progress)和publishProgress方法的参数

3、Result

onPostExecute(Result)方法的参数,也是doInBackground()方法的返回值

如果是使用匿名内部类,泛型参数则在声明的使用就需要设置、确定:

new AsyncTask<String, Void, Bitmap>() {
@Override
protected Bitmap doInBackground(String... params) {
return null;
}
}.execute("");
如果是新建类继承自AsyncTask,在定义类时设置:

class DownLoadAsyncTask extends AsyncTask<String, Integer, Boolean>

三、AysncTask的具体使用

public class AsyncTaskDownLoadActivity extends AppCompatActivity {
Button mDownLoadBtn;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_async_task_down_load_layout);
mDownLoadBtn = (Button) findViewById(R.id.start_download_btn);
mDownLoadBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
DownLoadAsyncTask downLoadAsyncTask = new DownLoadAsyncTask(AsyncTaskDownLoadActivity.this);
downLoadAsyncTask.execute("下载地址");//开始执行后台异步任务
}
});
}

class DownLoadAsyncTask extends AsyncTask<String, Integer, Boolean> {
Context mContext;
ProgressDialog mProgressDialog;

public DownLoadAsyncTask(Context context) {
mContext = context;
mProgressDialog = new ProgressDialog(context);//实例化一个进度条对话框
}

@Override
protected void onPreExecute() {
Log.v("AsyncTask", "onPreExecute()");
super.onPreExecute();
mProgressDialog.show();//初始化操作,显示对话框
}

@Override
protected void onProgressUpdate(Integer... values) {
Log.v("AsyncTask", "onProgressUpdate()");
super.onProgressUpdate(values);
mProgressDialog.setMessage("已经下载了" + values[0] + "%");//更新进度条对话框
}

@Override
protected Boolean doInBackground(String... params) {
Log.v("AsyncTask", "doInBackground()");
int n = 1;
while (n <= 10) {
Random random = new Random();
n = n + random.nextInt(5);
//设置随机数,模拟下载
SystemClock.sleep(500);
publishProgress(n);//通过调用publishProgress()方法,使AysncTask回调onProgressUpdate(),并传入数据n
}
return true;
}

@Override
protected void onPostExecute(Boolean aBoolean) {
Log.v("AsyncTask", "onPostExecute()");
super.onPostExecute(aBoolean);
mProgressDialog.dismiss();//取消进度条对话框显示
if (aBoolean)
Toast.makeText(mContext, "下载完成", Toast.LENGTH_LONG).show();
else
Toast.makeText(mContext, "下载失败", Toast.LENGTH_LONG).show();
}
}
}

为了方便理解几个方法的调用时机和执行顺序,可以打印日志,观察一下:



注:

(1)AsyncTask实例必须在UI线程中创建

(2)AsyncTask.execute()必须在主线程中执行

(3)AysnTask默认是单线程执行,内部有一个任务队列,从任务队列中取出任务执行完成过后才会开始执行下一个任务。

如果需要使用AysncTask执行多线程并发任务可以通过.executeOnExecutor()方法来启动
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: