相信很多小伙伴都对AsyncTask有一定了解,但是网上的理论解释五花八门自己摸不着头脑,怎么办?这个时候一定要记得去看官方API,因为每个人读同一本书的理解还不一样呢,多看看原著自然就有自己的理解

AsyncTask官方API

1 来看看官方解释

这里写图片描述

注意AsyncTask其实是一个抽象类,里面有一些常用的抽象方法(后续会讲)

AsyncTask enables proper and easy use of the UI thread. This class allows you to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.

AsyncTask is designed to be a helper class around Thread and Handler and does not constitute a generic threading framework. AsyncTasks should ideally be used for short operations (a few seconds at the most.) If you need to keep threads running for long periods of time, it is highly recommended you use the various APIs provided by the java.util.concurrent package such as Executor, ThreadPoolExecutor and FutureTask.

An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread. An asynchronous task is defined by 3 generic types, called Params, Progress and Result, and 4 steps, called onPreExecute, doInBackground, onProgressUpdate and onPostExecute.

不知道大家英文水平如何,在这里给大家大致翻译一下这几段英文的大致意思
1 AsyncTask 能够更适合更容易配合UI线程使用,这个类可以允许你在UI线程中执行后台操作和发布结果(可以理解为刷新UI界面)而不必操作线程或者Handler
2 AsyncTask 被设计成一个Handler和线程的辅助类,并不组成通用的线程框架。AsyncTask 应该在短时间操作中使用(最多几秒钟),如果你需要保持线程长时间运行,强烈推荐你使用java.util.concurrent包提供的各种各样的API,例如Executor,ThreadPoolExecutor ,FutureTask
3 AsyncTask 定义需要三个通用的类型,叫做Params,Progress和Result,并且有四个步骤onPreExecute,doInBackground,onProgressUpdate ,onPostExecute

2 通用类型?抽象方法?

通用类型

  1. Params是指调用execute()方法时传入的参数类型和doInBackgound()的参数类型
  2. Progress是指更新进度时传递的参数类型,即publishProgress()和onProgressUpdate()的参数类型
  3. Result是指doInBackground()的返回值类型

抽象方法

  1. doInBackgound() 这个方法是继承AsyncTask必须要实现的,运行于后台,耗时的操作可以在这里做
  2. publishProgress() 更新进度,给onProgressUpdate()传递进度参数
  3. onProgressUpdate() 在publishProgress()调用完被调用,更新进度
  4. 最简单两个抽象方法在代码里面讲

3 好像不是那么懵逼了

一起来用代码加深理解吧!

new AsyncTask<String, Float, String>() {//第一个表示网络请求(url),第二个是用来动态显示你后台线程计算完成的百分比,第三个是表示后台线程计算完的结果
                    @Override
                    protected void onPreExecute() {//在后台开始操作之前调用,在主线程中进行
                        Log.i("TAG", "onPreExecute");
                        super.onPreExecute();
                    }

                    @Override
                    protected void onPostExecute(String s) {//后台计算完返回的结果,用来修改UI界面,在UI线程中进行
                        Log.i("TAG", s);
                        onCancelled();
                        onCancelled(s);
                        super.onPostExecute(s);
                    }

                    @Override
                    protected void onProgressUpdate(Float... values) {//不断地更新进度,在主线程中
                        Log.i("TAG", "onProgressUpdate  "+values[0]);
                        super.onProgressUpdate(values);
                    }

                    @Override
                    protected String doInBackground(String... params) {//后台操作开始进行耗时操作,注意这里面不能进行UI操作,因为是在子线程中
                        Log.i("TAG", "doInBackground");
                        try {
                            URL url = new URL(params[0]);
                            URLConnection c = url.openConnection();
                            long total = c.getContentLength();
                            InputStream in = c.getInputStream();
                            InputStreamReader is = new InputStreamReader(in);
                            BufferedReader bf = new BufferedReader(is);
                            String line;
                            StringBuilder sb = new StringBuilder();
                            while ((line=bf.readLine())!=null){
                                sb.append(line);
                                publishProgress((float) (sb.toString().length()/total));//这个方法是通知onProgressUpdate更新进度
                            }
                            bf.close();
                            in.close();
                            return sb.toString();
                        } catch (MalformedURLException e) {
                            e.printStackTrace();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        return null;
                    }
                }.execute("https://news.baidu.com");//执行网络请求,注意现在是https协议

这里写图片描述
这里写图片描述

1 调用顺序确实如API介绍所示
2 代码里面没有自定义Handler或者Thread就可以修改UI线程,很方便
3 类里面还有网络请求取消的方法,暂不研究,有兴趣的同学可以尝试下哈~

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐