AsyncTask
AsyncTask的执行分为四个步骤,每一步都对应一个回调方法,这些方法不应该由应用程序调用,开发者需要做的就是实现这些方法。
1) 继承AsyncTask
2) 实现AsyncTask中定义的下面一个或几个方法
onPreExecute(), 该方法将在执行实际的后台操作前被UI thread调用。可以在该方法中做一些准备工作,如在界面上显示一个进度条。
doInBackground(Params...), 将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。这里将主要负责执行那些很耗时的后台计算工作。可以调用 publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。
onProgressUpdate(Progress...),在publishProgress方法被调用后,UI thread将调用这个方法从而在界面上展示任务的进展情况,更新一个进度条。
onPostExecute(Result), 在doInBackground 执行完成后,onPostExecute 方法将被UI thread调用,后台的计算结果将通过该方法传递到UI thread。
为了正确的使用AsyncTask类,以下是几条必须遵守的准则:
1) Task的实例必须在UI thread中创建
2) execute方法必须在UI thread中调用
3) 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法
4) 该task只能被执行一次,否则多次调用时将会出现异常
doInBackground方法和onPostExecute的参数必须对应,这两个参数在AsyncTask声明的泛型参数列表中指定,第一个为doInBackground接受的参数,第二个为显示进度的参数,第三个为doInBackground返回和onPostExecute传入的参数。
从网上下载图片的例子:
在主线程中
new MyAsycTask().execute("图片网址");
写一个内部类继承AsyncTask
/** * 三个泛型 * 第一个,Params表示启动任务执行的输入参数,这里传网址使用String * 第二个,Progress 后台任务执行的百分比,这里使用Integer。 * 第三个,Result 后台执行任务最终返回的结果,这里返回一个Bitmap对象。 * */ class MyAsycTask extends AsyncTask<String, Integer, Bitmap>{ /** * 此方法在doInBackground前被调用,可以用来做一些初始化工作 */ protected void onPreExecute() { //将progressBar最大值设为100 progressBar.setMax(100); //初始化progressBar初始位置为0 progressBar.setProgress(0); } /** * 此方法在后台线程执行,必须实现,用来做一些好是操作,期间可以使用publishProgress(Progress)方法向主线程传递消息 * */ protected Bitmap doInBackground(String... params) { //获取传进来的参数(图片网址) String str=params[0]; //定义一个Bitmap对象 Bitmap bitmap=null; try { //定义一个URL对象,可理解为一个网址对象 URL url=new URL(str); //定义一个URLConnection对象,即打开一个连接,通过URL的openConnection()方法 URLConnection conn=url.openConnection(); //从打开的连接获取一个输入流 InputStream is=conn.getInputStream(); ByteArrayOutputStream baos=new ByteArrayOutputStream(); //用来接收每次获取的字节数初始化为-1 int b=-1; //获取图片总的大小 用来更新ProgressBar int total=conn.getContentLength(); //当前读取到的位置 int current=0; //每次读取128字节 byte []buffer=new byte[128]; //循环读取 while((b=is.read(buffer))!=-1){ current+=128; //往baos写数据 baos.write(buffer,0,b); //向主线程发送当前读取位置 publishProgress(current*100/total); } byte[] imageBuffer=baos.toByteArray(); bitmap=BitmapFactory.decodeByteArray(imageBuffer, 0, imageBuffer.length); } catch (IOException e) { e.printStackTrace(); //手动抛出异常 throw new RuntimeException(e); } return bitmap; } /** * 当publishProgress(Progress)方法执行后主线程会调用此方法,可以在此方法内更新界面控件 */ protected void onProgressUpdate(Integer... values) { //更新ProgressBar progressBar.setProgress(values[0]); } /** * 当doInBackground()方法结束后调用此方法,可用来更新界面 */ protected void onPostExecute(Bitmap result) { //设置图片 imageView.setImageBitmap(result); } }