Android AsyncTask的使用

AsyncTask方便我们在子线程进行耗时操作,并且方便切换到UI线程进行更新UI,不需要再使用Handler等在子线程与主线程之间进行通信了。

AsyncTask的基本用法

AsyncTask是一个抽象类,因此使用它就要写一个类继承它,继承的时候需要指定三个泛型参数

  1. Params
    在执行后台任务时需要传入的参数类型,doInbackground()方法的参数
  2. Progress
    如果需要在界面上显示执行的任务进度,则使用这里指定的泛型指定的类型作为进度单位,onProgressUpdate()方法和publishProgress()方法的参数
  3. Return
    任务执行完成后,如果需要返回值,就使用这里指定的泛型作为返回值的类型,doInbackground()方法的返回类型以及onPostExecute()方法的参数

重写他的几个方法,一个简单的AsyncTask就可以写成

class MyAsyncTask extends AsyncTask<Void, Integer, Boolean>{
        @Override
        protected void onPreExecute() {
            // TODO Auto-generated method stub
            super.onPreExecute();
        }

        @Override
        protected Boolean doInBackground(Void... params) {
            // TODO Auto-generated method stub
            return null;
        }
        @Override
        protected void onProgressUpdate(Integer... values) {
            // TODO Auto-generated method stub
            super.onProgressUpdate(values);
        }
        @Override
        protected void onPostExecute(Boolean result) {
            // TODO Auto-generated method stub
            super.onPostExecute(result);
        }
    }

重写的这四个方法为

  1. onPreExecute()
    这个方法会在任务开始前进行调用,在这里可以执行一些准备工作,例如显示一个进度条等。
  2. doInbackground(Void…params)
    执行任务的方法,这个方法是在子线程中执行的,因此可以执行一些耗时任务,执行完毕后需要用return语句进行返回,返回的类型就是继承AsyncTask时定义的第三个参数,如果定义为Void,则不需要返回,定义为Integer,就返回Integer类型。注意,由于该方法是在子线程中执行的,因此不可以更新UI,如果需要更新UI,应该调用publishProgress(Progress…)方法完成。
  3. onProgressUpdate(Integer…values)
    当后台任务中调用了publishProgress(Progress…)方法后,这个方法很快便会被调用,方法中的参数就是publishProgress(Progress)方法传递进来的参数,该方法可以利用传递进来的参数更新UI,例如更新进度条的进度。
  4. onPostExecute(Boolean…result)
    当后台任务执行完毕,通过return语句进行返回后,该方法马上会被调用,返回的结果作为参数传递到该方法中。在该方法中可以进行UI操作,例如提示任务完成,关闭进度条等。

使用实例(后台下载图片,并显示)

继承AsyncTask,泛型分别为URL,Integer,Boolean,说明下载任务需要传递一个URL参数,然后更新进度是Integer类型,返回结果是Boolean类型

class DownloadAsyncTask extends AsyncTask<URL, Integer, Boolean>

重写onPreExecute方法

在这里,定义了一个进度条,显示在主界面

@Override
        //运行前的准备
        protected void onPreExecute() {

            dialog=new ProgressDialog(MainActivity.this);
            dialog.setTitle("下载进度");
            dialog.setMax(100);
            dialog.setCancelable(true);
            dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            dialog.show();
        }

重写doInbackground方法

传递进来需要下载的Url地址,然后通过HttpURLConnection访问网络,通过IO流进行下载图片,然后计算进度,由于图片太小,下载的太快,所以我在这里每读取一次byte[1024],就使线程休眠100毫秒,没读取一次就计算一次进度,然后publishProgress方法通知更新进度条

    @Override
        protected Boolean doInBackground(URL... params) {
            HttpURLConnection connection=null;
            int contentLenth=0;
            try {
                connection=(HttpURLConnection) params[0].openConnection();
                connection.setConnectTimeout(4000);
                connection.setReadTimeout(4000);
                connection.setRequestMethod("GET");
                contentLenth=connection.getContentLength();
                File file=new File(getCacheDir()+"xu.jpg");
                InputStream in=connection.getInputStream();
                FileOutputStream out=new FileOutputStream(file);
                byte[] b=new byte[1024];
                int len=0;
                int totalSize=0;
                while((len=in.read(b))!=-1){
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    out.write(b, 0, len);
                    totalSize+=len*100;
                    int progress=(totalSize/contentLenth);
                    publishProgress(progress);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

            return true;
        }

重写onProgressUpdate方法

通过publishProgress方法传递进来的进度更新进度条的进度。


        @Override
        protected void onProgressUpdate(Integer... values) {
            dialog.setProgress(values[0]);
        }

重写onPostExecute方法

如果返回的是true,就显示下载成功,并将图片显示出来通过BitmapFactory.decodeStream(file)方法得到一个Bitmap对象,然后显示在ImageView中。

@Override
        protected void onPostExecute(Boolean result) {
            dialog.dismiss();
            if(result){
                Toast.makeText(MainActivity.this, "下载成功", Toast.LENGTH_LONG).show();
                File file=new File(getCacheDir()+"xu.jpg");
                Bitmap bitmap=null;
                try {
                    bitmap = BitmapFactory.decodeStream(new FileInputStream(file));
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
                mShowImageView.setImageBitmap(bitmap);

            }else{
                Toast.makeText(MainActivity.this, "下载失败", Toast.LENGTH_LONG).show();
            }
        }

调用执行

界面一打开,就开始下载,然后完成后在ImageView上显示


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mShowImageView=(ImageView) findViewById(R.id.main_show_ImageView);
        try {
            new DownloadAsyncTask().execute(new URL("https://ss0.bdstatic.com/94oJfD_bAAcT8t7mm9GUKT-xh_/timg?image&quality=100&size=b4000_4000&sec=1465108635&di=d36b371b3eeb89bf304ccfbee2b4f1cd&src=http://picture.youth.cn/dmzb/201305/W020130514542662922703.jpg"));
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
    }

运行结果

这里写图片描述

这里写图片描述

这里写图片描述

可以看到已经成功了,注意别忘了配置网络访问权限!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值