Android_AsyncTask

来源:互联网 发布:朝鲜第五次核试验 知乎 编辑:程序博客网 时间:2024/06/06 01:26

Android_AsyncTask

我在上一篇的Blog中介绍了Android中多线程之间的通信–Handler消息机制,如果你不是那么的理解。今天就让我们学习一下,Android帮我们做了很好的一个封装工具—AsyncTask(AsyncTask可以十分简单的从子线程切换到主线程。)

在学习AsyncTask之前,我们还是先了解一下AsyncTask是什么?使用它需要传入那些参数。和它都具有什么方法。

AsyncTask是一个自动在子线程执行任务,并且自动实现了在主线程对进度和结果更新的一个异步任务类,开发者只需要将不同的代码重写在不同的方法即可。

继承AsyncTask参数说明

AsyncTask是一个抽象类,通常需要自定义类,继承自AsyncTask,
在继承时,需要指定3个泛型的数据类型,分别表示:
1、(params)执行任务时所需要的参数的数据类型、
2、(Progress)执行任务过程中如果需要更新进度,表示进度的数据类型、
3、(Result)执行任务完成之后,结果的数据类型
部分任务可能不需要以上3种中的某些数据类型,通常使用Void类型进行标识。

AsyncTask中的方法

1、onPreExecute()
这个方法会在后台任务开始执行之前调用,用于进行一些界面上的初始化操作,比如显示一个进度条对话框。
2、doInBackground(Params …)
这个方法中的所有代码都是在子线程中运行,我们应该在这里去处理所有的耗时任务。任务一单完成就可以通过return语句来讲任务的执行结果返回,如果AsyncTask的第三个泛型参数指定的是Void,就可以不返回任务执行结果。注意,在这个方法中是不可以进行UI操作的,如果需要更新UI元素,比如说反馈当前任务的执行进度,可以调用publicProgress(Progress…)
3、onProgressUpdate(Progress…)
当在后台任务中调用了publicProgress(Progress…)方法后,这个方法就会很快被调用,方法中携带的参数就是在后台任务中传递过来的。在这个方法中可以对UI进行操作,利用参数中的数值可以对界面元素进行相应地更新。
4、onPostExecute(Result)
当后台任务执行完毕并通过return语句进行返回时,这个方法就很快会被调用。返回的数据会作为参数传递到此方法中,可以利用返回的数据来进行一些UI操作,比如关闭掉进度条对话框。

通过对上面对AsyncTask的讲解,你应该没有那么迷茫了,现在我们就通过一个小实例来具体的体会一下吧。我的这个实例很简单,就是点击按钮去下载网络中的一张图片,并显示在ImageView中。

1、下面先给大家我的activity_main.xml布局文件的代码:

<?xml version="1.0" encoding="utf-8"?><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"    tools:context="com.example.asynctasktest.MainActivity">    <Button        android:id="@+id/main_DownloadBtn"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="点击下载图片"        android:textSize="18sp" />    <ImageView        android:id="@+id/main_iv_show"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_below="@+id/main_DownloadBtn"        android:src="@mipmap/ic_launcher"/></RelativeLayout>

2、下面让我们来看一下MainActivity中的具体逻辑代码:

public class MainActivity extends Activity {    private Button downLoadBtn;    private ImageView ivShowImage;    //图片的URL    private String IMAGE_PATH = "http://d.hiphotos.baidu.com/image/w%3D2048/sign=232a6514be315c6043956cefb989ca13/c83d70cf3bc79f3d3b082d31b8a1cd11738b29c2.jpg";    private ProgressDialog dialog;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        //设置Activity没有标题栏        requestWindowFeature(Window.FEATURE_NO_TITLE);        setContentView(R.layout.activity_main);        downLoadBtn = (Button) findViewById(R.id.main_DownloadBtn);        ivShowImage = (ImageView) findViewById(R.id.main_iv_show);        dialog = new ProgressDialog(this);        //用户不可以点击取消        dialog.setCancelable(false);        dialog.setMessage("正在下载图片,请耐心等待--");        //显示一个百分比进度条,不加就显示默认的圈圈        dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);        downLoadBtn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                new InnerAsyncTask().execute(IMAGE_PATH);            }        });    }    /***     * 自定义InnerAsyncTask继承AsyncTask     */    class InnerAsyncTask extends AsyncTask<String, Integer, byte[]> {        //使用HttpURLConnection请求,我在AndroidStudio中没有发现HttpClient        HttpURLConnection connection = null;        URL url = null;        InputStream inputStream = null;        //返回的图片的内容        byte[] result = null;        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();        @Override        protected void onPreExecute() {            super.onPreExecute();            //显示进度条            dialog.show();        }        @Override        protected byte[] doInBackground(String... params) {            try {                url = new URL(params[0]);                connection = (HttpURLConnection) url.openConnection();                int file_length = connection.getContentLength();                int totle_length = 0;                byte[] data = new byte[1024];                int len = 0;                if (connection.getResponseCode() == 200) {                    inputStream = connection.getInputStream();                    while ((len = inputStream.read(data)) != -1) {                        totle_length += len;                        int progress_value = (int) (totle_length / (float) file_length);                        //发布刻度单位                        publishProgress(progress_value);                        outputStream.write(data, 0, len);                    }                }                result = outputStream.toByteArray();            } catch (MalformedURLException e) {                e.printStackTrace();            } catch (IOException e) {                e.printStackTrace();            } finally {                if (connection != null) {                    connection.disconnect();                }            }            return result;        }        @Override        protected void onProgressUpdate(Integer... values) {            super.onProgressUpdate(values);            //设置进度条的显示进度            dialog.setProgress(values[0]);        }        @Override        protected void onPostExecute(byte[] result) {            super.onPostExecute(result);            Bitmap bm = BitmapFactory.decodeByteArray(result, 0, result.length);            //给ImageView设置Bitmap对象            ivShowImage.setImageBitmap(bm);            //显示出来图片后将进度条消失            dialog.dismiss();        }    }}

注意

AsyncTask的执行特性是一把双刃剑,当存在多个AsyncTask时,所有的AsyncTask会依据启动的顺序依次执行,而并不会存在多个任务的多个子线程同时运行的状况

如果你感觉上面的内容比较简单,可以看一下AsyncTask的源码讲解:

AsyncTask源码讲解

0 0
原创粉丝点击