AsyncTask(异步通信)

来源:互联网 发布:人工智能的弊端有哪些 编辑:程序博客网 时间:2024/05/16 23:58

先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的生命周期进行绑定

0 0
原创粉丝点击