内容字号:默认大号超大号

段落设置:段首缩进取消段首缩进

字体设置:切换到微软雅黑切换到宋体

Android:多线程之AsyncTask

2016-07-21 15:01 出处:电脑高手网整理 人气: 评论(0

 AsyncTask

  AsyncTask,异步任务,可以简单进行异步操作,并把执行结果发布到UI主线程。AsyncTask是一个抽象类,它的内部其实也是结合了Thread和Handler来实现异步线程操作,但是它形成了一个通用线程框架,更清晰简单。AsyncTask应该被用于比较简短的操作(最多几秒钟)。如果需要保持长时间运行的线程,可以使用ThreadPooExecutor或者FutureTask,关于这两个类的内容,以后再介绍,本片博客主要介绍AsyncTask。

  AsyncTask被定义为一个操作,运行在一个后台线程中,其结果被发布在UI线程上。它的异步工作的参数与返回值被泛型的三个参数指定:Params、Progress、Result。AsyncTask将经历4个步骤:onPreExecute、doInBackground、onProgressUpdate、onPostExecute。下面详细讲解这三个参数与四个步骤:

  三个泛型参数:

  • Params:被发送到执行任务的参数类型。
  • Progress:进度的类型,发送后台的计算进度到UI线程类型。
  • Result:异步任务的返回结果类型。
  •   一个异步任务将经历四个阶段:

    • onPreExecute():执行在UI线程上调用执行任务之前,一般用于设置任务。
    • doInBackground(Params...):主要是用来执行异步任务的耗时操作,可以在这个方法中通过publishProgress()方法发布进度信息,并在执行完成之后,返回执行结果。
    • onProgreddUpdate(Progress...):在UI线程上接受doInBackground()传递过来的进度信息,并在UI线程上展示进度信息,它执行的时机是不确定的。
    • onPostExecute(Result):在UI线程上操作doInBackground()执行的返回值。
    •   上面介绍的四个步骤的示意图:

      AsyncTask取消任务

        在程序的任何位置,都可以通过cancel(boolean)方法进行取消任务,当取消任务之后,会改变isCancelled()的返回值,使其返回true。之后会调用onCancelled(Object)方法,替代onPostExecute()得到doInBackground()的返回结果。在运行中,可以经常通过isCancelled()方法查看任务是否被取消。

       

      AsyncTask的使用规则

        使用AsyncTask必须遵循以下规则:

        %20%20%20%20
      • AsyncTask必须声明在UI线程上。
      • %20%20%20%20
      • AsyncTask必须在UI线程上实例化。
      • %20%20%20%20
      • 必须通过execute()方法执行任务。
      • %20%20%20%20
      • 不可以直接调用onPreExecute()、onPostExecute(Resut)、doInBackground(Params...)、onProgressUpdate(Progress...)方法。
      • %20%20%20%20
      • 可以设置任务只执行一次,如果企图再次执行会报错。
      • 示例

          一个简单的示例,通过AsyncTask下载一个网络上的图片,下载的时候展示一个等待框,并显示在一个ImageView中。

          实现代码:

        %201%20package%20com.bgxt.datatimepickerdemo;
        %202%20
        %203%20import%20org.apache.http.HttpEntity;
        %204%20import%20org.apache.http.HttpResponse;
        %205%20import%20org.apache.http.client.HttpClient;
        %206%20import%20org.apache.http.client.methods.HttpGet;
        %207%20import%20org.apache.http.impl.client.DefaultHttpClient;
        %208%20import%20org.apache.http.util.EntityUtils;
        %209%20
        10%20import%20android.app.Activity;
        11%20import%20android.app.ProgressDialog;
        12%20import%20android.graphics.Bitmap;
        13%20import%20android.graphics.BitmapFactory;
        14%20import%20android.os.AsyncTask;
        15%20import%20android.os.Bundle;
        16%20import%20android.view.View;
        17%20import%20android.widget.Button;
        18%20import%20android.widget.ImageView;
        19%20
        20%20public%20class%20AsyncTaskActivity1%20extends%20Activity%20{
        21%20%20%20%20%20private%20Button%20btnDown;
        22%20%20%20%20%20private%20ImageView%20ivImage;
        23%20%20%20%20%20private%20static%20String%20image_path%20=%20"http://ww4.sinaimg.cn/bmiddle/786013a5jw1e7akotp4bcj20c80i3aao.jpg";
        24     private ProgressDialog dialog;
        25 
        26     @Override
        27     protected void onCreate(Bundle savedInstanceState) {
        28         // TODO Auto-generated method stub
        29         super.onCreate(savedInstanceState);
        30         setContentView(R.layout.asynctask_activity);
        31 
        32         btnDown = (Button) findViewById(R.id.btnDown);
        33         ivImage = (ImageView) findViewById(R.id.ivSinaImage);
        34         
        35         // 声明一个等待框以提示用户等待
        36         dialog=new ProgressDialog(this);
        37         dialog.setTitle("提示信息");
        38         dialog.setMessage("正在下载,请稍后...");
        39         
        40         btnDown.setOnClickListener(new View.OnClickListener() {
        41 
        42             @Override
        43             public void onClick(View v) {
        44                 // 执行一个异步任务,并把图片地址以参数的形式传递进去
        45                 new MyTask().execute(image_path);
        46             }
        47         });
        48     }
        49 
        50     // 以String类型的参数,Void表示没有进度信息,Bitmap表示异步任务返回一个位图
        51     public class MyTask extends AsyncTask<String, Void, Bitmap> {
        52         // 表示任务执行之前的操作
        53         @Override
        54         protected void onPreExecute() {
        55             super.onPreExecute();
        56             //显示等待框
        57             dialog.show();
        58         }
        59 
        60         //主要是完成耗时操作
        61         @Override
        62         protected Bitmap doInBackground(String... params) {
        63             HttpClient httpClient=new DefaultHttpClient();
        64             HttpGet httpGet=new HttpGet(params[0]);
        65             Bitmap bitmap=null;
        66             try {
        67                 //从网络上下载图片
        68                 HttpResponse httpResponse =httpClient.execute(httpGet);
        69                 if(httpResponse.getStatusLine().getStatusCode()==200){
        70                     HttpEntity httpEntity = httpResponse.getEntity();
        71                     byte[] data=EntityUtils.toByteArray(httpEntity);
        72                     bitmap=BitmapFactory.decodeByteArray(data, 0, data.length);                    
        73                 }
        74             } catch (Exception e) {
        75                 e.printStackTrace();
        76             }
        77             return bitmap;
        78         }
        79         
        80         //完成更新UI操作
        81         @Override
        82         protected void onPostExecute(Bitmap result) {
        83             // TODO Auto-generated method stub
        84             super.onPostExecute(result);
        85             //设置ImageView的显示图片
        86             ivImage.setImageBitmap(result);
        87             // 销毁等待框
        88             dialog.dismiss();
        89         }
        90 
        91     }
        92 }

          效果展示:

          

          上面的Demo并没有用到进度的信息,下面再提供一个完整的AsyncTask的Demo,同样是下载一个图片,并且展示到一个ImageView中,但是这里在下载的过程中增加一个进度条对话框,用于展示下载的进度。

          实现代码:

        %20%201%20package%20com.bgxt.datatimepickerdemo;
        %20%202%20
        %20%203%20import%20java.io.ByteArrayOutputStream;
        %20%204%20import%20java.io.InputStream;
        %20%205%20
        %20%206%20import%20org.apache.http.HttpResponse;
        %20%207%20import%20org.apache.http.client.HttpClient;
        %20%208%20import%20org.apache.http.client.methods.HttpGet;
        %20%209%20import%20org.apache.http.impl.client.DefaultHttpClient;
        %2010%20
        %2011%20import%20android.app.Activity;
        %2012%20import%20android.app.ProgressDialog;
        %2013%20import%20android.graphics.Bitmap;
        %2014%20import%20android.graphics.BitmapFactory;
        %2015%20import%20android.os.AsyncTask;
        %2016%20import%20android.os.Bundle;
        %2017%20import%20android.view.View;
        %2018%20import%20android.widget.Button;
        %2019%20import%20android.widget.ImageView;
        %2020%20
        %2021%20public%20class%20AsyncTaskActivity2%20extends%20Activity%20{
        %2022%20%20%20%20%20private%20Button%20btnDown;
        %2023%20%20%20%20%20private%20ImageView%20ivImage;
        %2024%20%20%20%20%20private%20static%20String%20image_path%20=%20"http://ww4.sinaimg.cn/bmiddle/786013a5jw1e7akotp4bcj20c80i3aao.jpg";
         25     private ProgressDialog dialog;
         26 
         27     @Override
         28     protected void onCreate(Bundle savedInstanceState) {
         29         super.onCreate(savedInstanceState);
         30         setContentView(R.layout.asynctask_activity);
         31         btnDown = (Button) findViewById(R.id.btnDown);
         32         ivImage = (ImageView) findViewById(R.id.ivSinaImage);
         33 
         34         dialog = new ProgressDialog(this);
         35         dialog.setTitle("提示");
         36         dialog.setMessage("正在下载,请稍后...");
         37         dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
         38         dialog.setCancelable(false);
         39 
         40         btnDown.setOnClickListener(new View.OnClickListener() {
         41 
         42             @Override
         43             public void onClick(View v) {
         44                 //  执行异步任务
         45                 new MyTask().execute(image_path);
         46             }
         47         });
         48     }
         49 
         50     public class MyTask extends AsyncTask<String, Integer, Bitmap> {
         51         @Override
         52         protected void onPreExecute() {
         53             super.onPreExecute();
         54             dialog.show();
         55         }
         56 
         57         @Override
         58         protected void onProgressUpdate(Integer... values) {
         59             super.onProgressUpdate(values);
         60             // 设置进度对话框的进度值
         61             dialog.setProgress(values[0]);
         62         }
         63 
         64         @Override
         65         protected void onPostExecute(Bitmap result) {
         66             super.onPostExecute(result);
         67             dialog.dismiss();
         68             ivImage.setImageBitmap(result);
         69         }
         70 
         71         @Override
         72         protected Bitmap doInBackground(String... params) {
         73             Bitmap bitmap = null;
         74             ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
         75             InputStream inputStream = null;
         76             try {
         77                 HttpClient httpClient = new DefaultHttpClient();
         78                 HttpGet httpGet = new HttpGet(params[0]);
         79                 HttpResponse httpResponse = httpClient.execute(httpGet);
         80                 if (httpResponse.getStatusLine().getStatusCode() == 200) {
         81                     inputStream = httpResponse.getEntity().getContent();
         82                     long file_length = httpResponse.getEntity()
         83                             .getContentLength();
         84                     int len = 0;
         85                     byte[] data = new byte[1024];
         86                     int total_length = 0;
         87                     // 以字节的方式读取图片数据
         88                     while ((len = inputStream.read(data)) != -1) {
         89                         total_length += len;
         90                         // 计算进度
         91                         int values = (int) ((total_length / (float) file_length) * 100);
         92                         // 发布进度信息
         93                         publishProgress(values);
         94                         outputStream.write(data, 0, len);
         95                     }
         96                     byte[] result=outputStream.toByteArray();
         97                     bitmap=BitmapFactory.decodeByteArray(result, 0, result.length);
         98                 }
         99             } catch (Exception e) {
        100                 e.printStackTrace();
        101             } finally {
        102                 try {
        103                     if (inputStream != null) {
        104                         inputStream.close();
        105                     }
        106                 } catch (Exception e2) {
        107                 }
        108             }
        109             return bitmap;
        110         }
        111     }
        112 }

          实现效果:

相关栏目

相关文章



分享给小伙伴们:

评论

发表评论愿您的每句评论,都能给大家的生活添色彩,带来共鸣,带来思索,带来快乐。

签名: 验证码: 点击我更换图片

评论列表

    Copyright © 2002-2016 dngsw.cn 电脑高手网 版权所有

    粤ICP备13005586号-3