码迷,mamicode.com
首页 > 其他好文 > 详细

AsyncTask(异步通信)

时间:2015-06-23 21:47:30      阅读:124      评论:0      收藏:0      [点我收藏+]

标签:异步

先new一个class继承AsyncTask类,AsyncTask要求提供三个泛型参数(Params 、Progress 、Result )其中,Params 为启动任务执行的输入参数,比如HTTP请求的URL;Progress 为后台任务执行的百分比;Result 后台执行任务最终返回的结果,比如String;然后AsyncTask的几个方法重写onPreExecute()、doInBackground()、onPostExecute()、onProgressUpdate(),其中doInBackground()为必须重写的;
例如:

class MyAsyncTask extends AsyncTask<Void, Void, Void>{

        //第一个调用的方法可以用来初始化一些数据
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            Log.i("info", "onPreExecute");
        }
        //用于异步处理的方法,此方法不在主线程中运行
        @Override
        protected Void doInBackground(Void... params) {
            publishProgress();
            Log.i("info", "doInBackground");
            return null;
        }
        //doInBackground方法结束时调用
        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            Log.i("info", "onPostExecute");
        }
        //只有doInBackground方法中调用了publishProgress()时才会执行
        @Override
        protected void onProgressUpdate(Void... values) {
            super.onProgressUpdate(values);
            Log.i("info", "onProgressUpdate");
        }
    }

值得注意的是这四个方法中只有doInBackground()方法不在主线程中运行,所以所有耗时操作我们将在doInBackground() 方法中进行,其他的三个方法都可以改变UI

下面来一个加载网上图片的案例:
布局文件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.asynctaskdemo.ImageTestActivity" >

    <ProgressBar
        android:id="@+id/pb_bar"
        style="?android:attr/progressBarStyleLarge"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:visibility="gone" />

    <ImageView
        android:id="@+id/iv_img"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true" />

</RelativeLayout>

Java文件:

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;

public class ImageTestActivity extends ActionBarActivity {
    private static final String URL = "https://www.baidu.com/img/bdlogo.png";
    private ImageView iv_img;
    private ProgressBar pb_bar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_image_test);
        iv_img = (ImageView) findViewById(R.id.iv_img);
        pb_bar = (ProgressBar) findViewById(R.id.pb_bar);
        MyscyncTask mTask = new MyscyncTask();
        mTask.execute(URL);
    }

    class MyscyncTask extends AsyncTask<String, Void, Bitmap> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pb_bar.setVisibility(View.VISIBLE);
        }

        @Override
        protected Bitmap doInBackground(String... params) {
            String url = params[0];
            HttpURLConnection conn = null;
            Bitmap bitmap = null;
            try {
                //线程休眠1秒,方便看进度条
                Thread.sleep(1000);
                conn = (HttpURLConnection) new URL(url).openConnection();
                InputStream is = conn.getInputStream();
                BufferedInputStream bis = new BufferedInputStream(is);
                bitmap = BitmapFactory.decodeStream(bis);
                bis.close();
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return bitmap;
        }

        @Override
        protected void onPostExecute(Bitmap result) {
            super.onPostExecute(result);
            pb_bar.setVisibility(View.GONE);
            iv_img.setImageBitmap(result);
        }

    }
}

为了方便查看代码所以我将AsyncTask写成了内部类
由于图片资源较小,所以我用了一个线程休眠1秒,方便查看进度条

再来一个模拟进度条的案例

布局文件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.asynctaskdemo.ProgressBarTestActivity" >

    <ProgressBar
        android:id="@+id/progressBar1"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true" />

</RelativeLayout>

Java文件:

import android.os.AsyncTask;
import android.os.AsyncTask.Status;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.ProgressBar;

public class ProgressBarTestActivity extends ActionBarActivity {
    private ProgressBar progressBar1;
    private MyAsyncTask mTask;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_progress_bar_test);
        progressBar1 = (ProgressBar) findViewById(R.id.progressBar1);
        mTask = new MyAsyncTask();
        mTask.execute();
    }
    //将AsyncTask的生命周期与Activity进行绑定
    @Override
    protected void onPause() {
        super.onPause();
        if(mTask != null && mTask.getStatus() == Status.RUNNING){
            mTask.cancel(true);
        }
    }
    class MyAsyncTask extends AsyncTask<Void, Integer, Void>{

        @Override
        protected Void doInBackground(Void... params) {
            for (int i = 0; i < 100; i++) {
                if(isCancelled()){
                    break;
                }
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                publishProgress(i);
            }
            return null;
        }
        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            if(isCancelled()) 
                return;
            progressBar1.setProgress(values[0]);
        }


    }

}

注意:由于AsyncTask底层是通过线程池进行作用的所以只有一个AsyncTask线程运行结束后另一个AsyncTask线程才可以运行,为了解决这一个为题,我们可以将AsyncTask的生命周期与Activity的生命周期进行绑定

AsyncTask(异步通信)

标签:异步

原文地址:http://blog.csdn.net/tuu_zed/article/details/46608691

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!