AsyncTaske简单理解
关于AsyncTask的解释,Google上面是这样说的:
AsyncTask enables proper and easy use of the UI thread. This class allows you to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread. An asynchronous task is defined by 3 generic types, called Params, Progress and Result, and 4 steps, called onPreExecute, doInBackground, onProgressUpdate and onPostExecute.
大概意思就是说“它使创建异步任务变得更加简单,不再需要编写任务线程和Handler实例即可完成相同的任务。一个异步任务通常是在后台运行的计算等然后将结果发送到UI主线程中去。通常情况下,异步任务被定义为3种通用类型,分别为:参数、过程以及结果和4个步骤,分别为“onPreExecute、doInBackground、onProgressUpdate、onPostExecute””这就是关于异步任务的大概说明。
怎么来理解AsyncTask呢?通俗一点来说,AsyncTask就相当于Android给我们提供了一个多线程编程的一个框架,其介于Thread和Handler之间,我们如果要定义一个AsyncTask,就需要定义一个类来继承AsyncTask这个抽象类,并实现其唯一的一个 doInBackgroud 抽象方法。要掌握AsyncTask,我们就必须要一个概念,总结起来就是: 3个泛型,4个步骤。
3个泛型
3个泛型指的是什么呢?我们来看看AsyncTask这个抽象类的定义,当我们定义一个类来继承AsyncTask这个类的时候,我们需要为其指定3个泛型参数:
public abstractclassAsyncTask
Params:这个泛型指定的是我们传递给异步任务执行时的参数的类型
Progress:这个泛型指定的是我们的异步任务在执行的时候将执行的进度返回给UI线程的参数的类型
Result:这个泛型指定的异步任务执行完后返回给UI线程的结果的类型
4个步骤
4个步骤:当我们执行一个异步任务的时候,其需要按照下面的4个步骤分别执行:
1、onPreExecute():
这个方法是在执行异步任务之前的时候执行,并且是在UI Thread当中执行的,通常我们在这个方法里做一些UI控件的初始化的操作,例如弹出要给ProgressDialog。
2、doInBackground(Params... params):
在onPreExecute()方法执行完之后,会马上执行这个方法,这个方法就是来处理异步任务的方法,Android操作系统会在后台的线程池当中开启一个worker thread来执行我们的这个方法,所以这个方法是在worker thread当中执行的,这个方法执行完之后就可以将我们的执行结果发送给我们的最后一个 onPostExecute 方法,在这个方法里,我们可以从网络当中获取数据等一些耗时的操作。
3、onProgressUpdate(Progess... values):
这个方法也是在UI Thread当中执行的,我们在异步任务执行的时候,有时候需要将执行的进度返回给我们的UI界面,例如下载一张网络图片,我们需要时刻显示其下载的进度,就可以使用这个方法来更新我们的进度。这个方法在调用之前,我们需要在 doInBackground 方法中调用一个 publishProgress(Progress) 的方法来将我们的进度时时刻刻传递给 onProgressUpdate 方法来更新。
4、onPostExecute(Result... result):
当我们的异步任务执行完之后,就会将结果返回给这个方法,这个方法也是在UI Thread当中调用的,我们可以将返回的结果显示在UI控件上。
为什么我们的AsyncTask抽象类只有一个 doInBackground 的抽象方法呢??原因是,我们如果要做一个异步任务,我们必须要为其开辟一个新的Thread,让其完成一些操作,而在完成这个异步任务时,我可能并不需要弹出要给ProgressDialog,我并不需要随时更新我的ProgressDialog的进度条,我也并不需要将结果更新给我们的UI界面,所以除了 doInBackground 方法之外的三个方法,都不是必须有的,因此我们必须要实现的方法是 doInBackground 方法。
**简单使用**
//进度框显示progressDialog =newProgressDialog(MainActivity.this);
progressDialog.setTitle("提示信息");
progressDialog.setMessage("正在下载中,请稍后......");
//设置setCancelable(false);
表示我们不能取消这个弹出框,等下载完成之后再让弹出框消失progressDialog.setCancelable(false);
//设置ProgressDialog样式为水平的样式progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
//下载类publicclassMyAsyncTaskextendsAsyncTask{
@Override
protectedvoidonPreExecute() {super.onPreExecute();
//在onPreExecute()中我们让ProgressDialog显示出来progressDialog.show();
}
@Override
protected Bitmap doInBackground(String... params) {
Bitmap bitmap =null;
try{
URL url =newURL(params[0]);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5*1000);
conn.setRequestMethod("GET");
InputStream inputStream = conn.getInputStream();
if(conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
int fileLength = conn.getContentLength();
ByteArrayOutputStream outStread =newByteArrayOutputStream();
byte[] buffer =newbyte[1024];
int length =0;
long total =0;
while((length = inputStream.read(buffer)) !=-1) {
【AsyncTaske简单理解】outStread.write(buffer,0, length);
total += length;
if(fileLength >0) {
publishProgress((int) (total *100/ fileLength));
}
}
outStread.close();
inputStream.close();
byte[] data = https://www.it610.com/article/outStread.toByteArray();
if(data !=null) {
bitmap = BitmapFactory.decodeByteArray(data,0, data.length);
}else{
Toast.makeText(MainActivity.this,"Image error!", Toast.LENGTH_LONG).show();
}returnbitmap;
}
}catch(Exception e) {
e.printStackTrace();
}returnnull;
}
@Override
protectedvoidonProgressUpdate(Integer... values) {super.onProgressUpdate(values);
//更新ProgressDialog的进度条progressDialog.setProgress(values[0]);
}
@Override
protectedvoidonPostExecute(Bitmap bitmap) {super.onPostExecute(bitmap);
imageView.setImageBitmap(bitmap);
try{
saveFile(bitmap,"netpic.jpg");
}catch(IOException e) {
e.printStackTrace();
}
progressDialog.dismiss();
}
}//在UI主线程中执行下载程序StringpicUrl ="http://img3.imgtn.bdimg.com/it/u=2437337628,1430863508&fm=214&gp=0.jpg";
newMyAsyncTask().execute(picUrl);
推荐阅读
- 深入理解Go之generate
- 考研英语阅读终极解决方案——阅读理解如何巧拿高分
- 由浅入深理解AOP
- 科学养胃,别被忽悠,其实真的很简单
- 逻辑回归的理解与python示例
- opencv|opencv C++模板匹配的简单实现
- 松软可口易消化,无需烤箱超简单,新手麻麻也能轻松成功~
- 「按键精灵安卓版」关于全分辨率脚本的一些理解(非游戏app)
- 简单心理2019春A期+32+张荣
- 深入理解|深入理解 Android 9.0 Crash 机制(二)