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);
        }


    }

 

posted on 2012-12-20 09:39  @与非  阅读(292)  评论(0编辑  收藏  举报