Android基础之AsyncTask详解,巨细哟

  1. 构建AsyncTask子类参数
    1. 因为他是一个抽象类所有继承他之后需要重写下面三个泛型参数
      • Params:启动任务时,输入参数的类型。
      • Progress:后台任务执行中返回进度值的类型
      • Result:后台执行任务完成后返回结果的类型
  2. 构建AsyncTask子类的回调方法
    • dolnBackground:必须重写,异步执行后台程序将要完成的任务。
    • onPreExecute:执行后台耗时操作前被调用,用户通常会做一些准备工作,如一些初始化的操作。
    • onPostExecute():当dolnBackground()完成后,系统会自动调用该方法,并将dolnBackground()方法的返回值传给该方法。顾名思义就是展示我们所处理完的一个结果。
    • onProgressUpdate():在dolnBackground()方法中调用publishProgress()方法更新任务就会触发该方法。
  3. 程序的调动顺序是:
    • onPreExecute——>dolnBackground——>onPostExecute(没有调用publishProgress ())
  4. 传递进度:在dolnBackground()中调用publishProgress()方法的时候,就可以将一个进度值作为一参数传给onProgressUpdate(),我们就可以在onProgressUpdate()中得到这个参数,从而应用于更新一个异步进程的完成进度。


实例:
  1. 下载图片,并且显示(只是下载到缓存中。程序kill后需要再次下载)
    • package com.example.administrator.android_asynctask;

      import android.app.Activity;
      import android.graphics.Bitmap;
      import android.graphics.BitmapFactory;
      import android.os.AsyncTask;
      import android.os.Bundle;
      import android.util.Log;
      import android.view.View;
      import android.widget.ImageView;
      import android.widget.ProgressBar;

      import java.io.BufferedInputStream;
      import java.io.ByteArrayOutputStream;
      import java.io.FilterInputStream;
      import java.io.IOException;
      import java.io.InputStream;
      import java.io.InputStreamReader;
      import java.net.HttpURLConnection;
      import java.net.URL;

      import java.net.URL;
      import java.net.URLConnection;

      /**
      * Created by Administrator on 2016/5/26.
      */
      public class ImageTestextends Activity {
      private ImageView imageView;
      private ProgressBar progressBar;
      private static String URL = "http://img4.duitang.com/uploads/item/201308/10/20130810135200_tyE55.jpeg";

      protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.image);
      imageView = (ImageView) findViewById(R.id.imageView1);
      progressBar = (ProgressBar) findViewById(R.id.pb);
      new MyAsyncTask_1().execute(URL);
      }

      class MyAsyncTask_1 extends AsyncTask<String, Void, Bitmap> {
      @Override
      //在doInBackground启动前 ,显示progressBar
      protected void onPreExecute() {
      super.onPreExecute();
      progressBar.setVisibility(View.VISIBLE);
      }

      @Override
      protected void onPostExecute(Bitmap bitmap) {
      super.onPostExecute(bitmap);
      //隐藏progressBar
      progressBar.setVisibility(View.GONE);
      //传递bimap
      imageView.setImageBitmap(bitmap);
      Log.d("xyx","onPostExecute_bitmap=" + bitmap);
      }

      @Override
      //参数是可变长数组
      //<URL类型,进度值类型,返回值类型>
      //doInBackground方法是开启一个异步线程做耗时操作的
      protected Bitmap doInBackground(String... params) {
      //取出对应的URL
      String url = params[0];
      Bitmap bitmap = null;
      Log.d("xyx","url=" + url);
      //定义网络链接对象
      //以前的
      // URLConnection connection;
      HttpURLConnection connection;
      //用于获取的数据的输入流
      InputStream inputStream = null;
      try {
      //通过openConnection方法获取connection对象,获取网络连接对象
      Thread.sleep(3000);
      //原来方法
      // connection = new URL(url).openConnection();
      connection = (HttpURLConnection) new URL(url).openConnection();
      connection.setDoInput(true);
      connection.setRequestMethod("GET");
      connection.connect();
      //获取一个输入流
      inputStream = connection.getInputStream();
      BufferedInputStream bis = new BufferedInputStream(inputStream);
      //通过,decodeStream解析输入流流
      bitmap = BitmapFactory.decodeStream(bis);
      inputStream.close();
      bis.close();
      } catch (IOException e) {
      e.printStackTrace();
      } catch (InterruptedException e) {
      e.printStackTrace();
      }
      return bitmap;
      }
      }
      }
  2. 模拟进度条
    • package com.example.administrator.android_asynctask;

      import android.app.Activity;
      import android.content.Intent;
      import android.os.AsyncTask;
      import android.os.Bundle;
      import android.widget.ProgressBar;
      import android.widget.TextView;

      import java.util.List;

      /**
       * Created by Administrator on 2016/5/27.
       */
      public class progressBarTest extends Activity {
          private ProgressBar pb;
          private TextView tv;
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.progress);
              pb= (ProgressBar) findViewById(R.id.pb2);
              new MyAsyncTask_ProgressBar().execute();
          }

          class MyAsyncTask_ProgressBar extends AsyncTask<Void, Integer, Void> {
              @Override
              protected Void doInBackground(Void... params) {
                  for (int i = 0; i <=100; i++) {
                      try {
                          Thread.sleep(300);
                          publishProgress(i);
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                  }
                  return null;
              }

              @Override
              protected void onProgressUpdate(Integer... values) {
                  super.onProgressUpdate(values);
                  pb.setProgress(values[0]);

              }
          }

      }
  3. 取消AsyncTask
    • AsyncTask机制:因为他的底层是线程池 ,所有多次开始——返回后,他会卡住只有等之前的Task全部完成后,才会开始新的Task,而且,我们doInBackground中用的是for循环,所以只有等for循环结束,才会去执行下一个Task;所以会造成,多次进入后,进度条就会卡住的BUG,如何解决呢?
    • 方案:
      • AsyncTask和Activaty的生命周期保持一致,也就是Activity生命周期走到onPause的时候,把AsyncTask干掉就好了。
    • package com.example.administrator.android_asynctask;
      
      import android.app.Activity;
      import android.content.Intent;
      import android.os.AsyncTask;
      import android.os.Bundle;
      import android.util.Log;
      import android.widget.ProgressBar;
      import android.widget.TextView;
      
      import java.util.List;
      
      /**
       * Created by Administrator on 2016/5/27.
       */
      public class progressBarTest extends Activity {
          private ProgressBar pb;
          private TextView tv;
          private MyAsyncTask MTP;
          MyAsyncTask_ProgressBar mb = new MyAsyncTask_ProgressBar();
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.progress);
              pb = (ProgressBar) findViewById(R.id.pb2);
              mb.execute();
          }
      
      
          protected void onPause() {
              super.onPause();
              if ((mb != null) && (mb.getStatus() == AsyncTask.Status.RUNNING)) {
                  //这只是把MTP标记为cancel状态,不是真正的取消了线程,那我就需要,
                  // 给doInBackground中的for循环设定判断条件,
                  // 并且给onProgressUpdate进行判断是否要更新
                  mb.cancel(true);
              }
          }
      
          class MyAsyncTask_ProgressBar extends AsyncTask<Void, Integer, Void> {
              @Override
              protected Void doInBackground(Void... params) {
                  for (int i = 0; i <= 100; i++) {
                      //是否有cancel状态
                      if (isCancelled()) {
                          break;
                      }
                      try {
                          Thread.sleep(300);
                          publishProgress(i);
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                  }
                  return null;
              }
      
              @Override
              protected void onProgressUpdate(Integer... values) {
                  super.onProgressUpdate(values);
                  if (isCancelled()) {
                      return;
                  }
                  pb.setProgress(values[0]);
      
              }
          }
      
      }
      

失败原因:
  1. 下载部分:
    • 内部类是要放在外部类里面的
    • 图片无法显示的原因:bitmap通过bitmap = BitmapFactory.decodeStream(bis);这方法无法获得bitmap值;
    • 解决办法,网址有问题,不是图片网址
    • 附带博客一个,解决其他问题:http://blog.csdn.net/andypan1314/article/details/6670320
     

总结:
  •  必须在UI线程中创建AsyncTask的实例
  • 必须在UI线程中调用AsyncTask的execute()方法
  • 重写的四个方法是系统自动调用的,不应手动调用
  • 每个AsyncTask只能被执行一次,多次调用将会引发异常
  • dolnBackground只有这方法是在其他线程的,其他方法都是在UI线程。
     
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值