Android_AsyncTask

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源码讲解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值