Android 中AsyncTask 的使用

   Android 中AsyncTask 的使用  


1、首先我们来看看AsyncTask 的介绍: 
    Handler 和 AsyncTask 都是android 中用来实现异步任务处理的方式;其中: 

    Handler 实例向 UI 线程发送消息,完成界面更新, 
        优点:对整个过程控制的比较精细; 
        缺点:代码相对臃肿,多个任务同时执行时,不易对线程进行精确的控制; 

    AsyncTask :比Handler 更轻量级一些,适用于简单的异步处理; 
        优点:简单 | 快捷 | 过程可控; 
        缺点:使用多个异步操作时就变得复杂起来; 

2、AsyncTask 的定义:(AsyncTask 定义了三种泛型类型) 
    public abstract class AsyncTask<Params,Progress,Result>{...} 

    说明: 
        Params :启动任务执行的输入参数,例如:HTTP 请求的URL; 
        Progress: 后台任务执行的百分比; 
        Result:后台执行任务最终返回的结果,比如String; 

3、AsyncTask 异步任务的执行步骤:(以下方法除execute(Params... params),在AsyncTask中重写),下列是相关方法的介绍: 

    A、execute(Params... params) : 
        执行一个异步任务,需要我们在UI线程中调用,触发任务 

    B、OnPreExecute(): 
        execute(Params... params)调用后立即执行,一般用于在执行后台任务前对UI做一些标记; 例如,可以在此处显示进度对话框; 

    C、doInBackground(Params.. params): 
        onPreExecute() 完成后执行,后台执行,处理比较耗时的操作;此处不能操作UI,执行的过程中调用publishProgress(Progress... values)来更新进度信息; 

    D、onProgressUpdate(Progress... values): 
        在调用publicshProgress(Progress... values)方法执行,直接将进度信息更新到UI组建上;此方法在主线程上执行,用于显示任务执行的进度; 

    E、onPostExecute(Result result): 
        此方法在主线程中执行,当后台的操作结束时,此方法会被调用,计算结果作为参数传递到此方法中,直接将结果显示到UI组建上。 

    F、cancel(); : 
        取消一个正在执行的任务,在UI线程中完成,用AsyncTask的对象进行调用,参数为true/false; 


4、使用AsyncTask 时注意事项: 
    A、异步任务实例必须在UI线程中创建; 
    B、execute(Params... params) 方法必须在UI线程中调用; 
    C、不要手动的调onPreExecute().doInBackground().onProgressUpdate().onPostExecute()这几个方法; 
    D、不能在doInBackground(Params... params) 中更改组件信息; 
    E、一个任务实例只能执行一次,如果执行第二次会抛出异常; 

5、案例:使用AsyncTask 实现图片的下载: 

    Activity类,主程序的入口:
 
public class MainActivity extends Activity {  
  
    // 程序入口  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        MyAsyncTask my = new MyAsyncTask();  
        my.execute("http://photocdn.sohu.com/20110927/Img320705637.jpg");  
    }  
  
}  

   AsyncTask 派生类,实现异步任务:  
 package com.sun.asynctask;  
  
import java.io.ByteArrayOutputStream;  
import java.io.InputStream;  
import java.net.HttpURLConnection;  
import java.net.URL;  
  
import org.apache.http.HttpConnection;  
import org.apache.http.HttpEntity;  
import org.apache.http.HttpResponse;  
import org.apache.http.HttpStatus;  
import org.apache.http.client.HttpClient;  
import org.apache.http.client.methods.HttpGet;  
import org.apache.http.impl.client.DefaultHttpClient;  
  
import android.graphics.Bitmap;  
import android.graphics.BitmapFactory;  
import android.os.AsyncTask;  
import android.util.Log;  
  
/** 
 * 异步任务,实现网页内容的获取 
 * 
 * 
 * 生成该类的对象,并调用execute方法之后 
 * 
 * 首先执行的是onProExecute() 方法, 
 * 
 * 其次执行的doInBackground()方法 
 */  
public class MyAsyncTask extends AsyncTask<String, Integer, Bitmap> {  
  
    /** 
     * 在execute() 方法执行后立即执行,运行在UI线程中, 
     * 在后台任务开始前执行,用于标识UI界面 
     */  
    protected void onPreExecute() {  
        super.onPreExecute();  
        Log.i("msg","onPreExecute()...");  
    }  
  
    /** 
     * 后台执行耗时的任务; 
     * 
     * 方法中的 String 参数对应 AsyncTask的第一个参数; 
     * 返回的 Bitmap 对应的是AsyncTask 的第三个参数; 
     * 
     *  该方法并不运行在UI线程中,主要用于异步操作,可以调用publishProgress()方法触发 
     *  onProgressUpdate对UI进行操作; 
     * 
     */  
    protected Bitmap doInBackground(String... params) {  
        Log.i("msg","doInBackground(String... params)...");  
  
        try {  
  
            /* 网络访问方式 二 */  
            /* 
            URL url = new URL(params[0]); 
            HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); 
            connection.connect(); // 开始连接 
            int zong = connection.getContentLength(); 
            InputStream is2 = connection.getInputStream(); 
            */  
  
            /*  开始网络访问数据  */  
            HttpGet hg = new HttpGet(params[0]); // 此处注意参数的用法  
            HttpClient hc = new DefaultHttpClient();  
            HttpResponse hr = hc.execute(hg); // 发送请求,得到响应  
  
            // 判断请求是否成功  
            if(hr.getStatusLine().getStatusCode() == HttpStatus.SC_OK){  
                Log.i("msg", "access success...");  
                HttpEntity he = hr.getEntity();  
                InputStream is = he.getContent(); // 获取输入流对象,好比搭桥  
                long total = he.getContentLength(); // 文件的总字节数  
  
                ByteArrayOutputStream baos = new ByteArrayOutputStream(); // 输出流,临时容器,用于装从is中流出的数据  
  
                byte[] buffer = new byte[1024]; // 缓存容器,每次装载1024 个字节数据  
                int len = 0; // 每次读的字节数  
                int curLen = 0 ; // 已读多少数据  
  
                while((len=is.read(buffer))!=-1){ // 当len !=-1 时,也就是还有数据可读  
                    Log.i("msg","begin read data..."+len+",total:"+total);  
                    baos.write(buffer, 0, len); // 向临时容器中装数据  
                    curLen=curLen+len; // 更新已读的数据  
  
                    /* 在UI显示当前读取的进度 , 调用次方法触发onProgressUpdate() 方法执行 */  
                    publishProgress((int)(((float)curLen/total)*100));  
                }  
  
                Bitmap bitmap = BitmapFactory.decodeByteArray(baos.toByteArray(), 0, (int)total);  
                is.close();  
                return bitmap;  
            }  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
  
        return null;  
    }  
  
    /** 
     * 括号中的参数:String 对应的是AsyncTask 的第三个参数,也就是 
     * 接收了 从doInBackground() 返回的结果; 
     * 此方法在 doInBackground() 方法执行结束后执行,运行在UI线程中, 
     * 可以对UI进行更新 
     */  
    protected void onPostExecute(Bitmap result) {  
        super.onPostExecute(result);  
        Log.i("msg","onPostExecute(String result)..."+result.getHeight());  
    }  
  
  
    /** 
     * 方法括号中的Integer 对应AsyncTask 中的第二个参数; 
     * 在doInBackground() 中每次调用publishProgress() 时被执行; 
     * 该方法是在UI线程中的,所以可以用于对UI进行更新 
     */  
    protected void onProgressUpdate(Integer... values) {  
        super.onProgressUpdate(values);  
  
        Log.i("msg","onProgressUpdate(Integer... values)..."+values[0]);  
    }  
  
  
    /** 
     * 图片的下载 
     */  
    public HttpURLConnection downPic(String urltemp){  
  
        try {  
            URL url = new URL(urltemp); // 确定连接地址  
            // 打开一个连接  
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();  
            connection.connect(); // 开始连接  
            return connection;  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        return null;  
    }  
  
  
  
}  



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值