什么是AsyncTask(或AsyncResult)以及它通常如何用于Android?

时间:2015-07-07 19:22:01

标签: java android

找不到这个概念。已经提到了

https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/os/AsyncResult.java

https://docs.oracle.com/javaee/6/api/javax/ejb/AsyncResult.html

编辑: 我认为我所指的AsyncResult是选择用来保存通用asynchronous operation结果的特定名称。 (后台操作将在完成后异步通知用户。)

上面的链接似乎只是这个概念的特定实现 作为参考,请参阅以下内容:

1 个答案:

答案 0 :(得分:2)

背景/理论

AsyncTask 允许您在后台线程上运行任务,同时将结果发布到UI线程。

  

用户应该始终能够与应用互动,因此重要   以避免使用诸如此类的任务阻止主(UI)线程   从网上下载内容。

     

这就是我们使用 AsyncTask

的原因      

它通过包装UI线程消息队列和处理程序提供了一个简单的接口,允许您发送和处理来自其他线程的可运行对象和消息

实施

AsyncTask 是一个通用类。 (它的构造函数需要参数化类型。)

它使用这些三种通用类型:

Params - 执行时发送给任务的参数类型。

Progress - 后台计算期间发布的进度单元的类型。

Result - 后台计算结果的类型。

  

并非所有类型都始终由异步任务使用。要将类型标记为未使用,只需使用类型Void:

     

private class MyTask extends AsyncTask<Void, Void, Void> { ... }

这三个参数对应于您可以在 AsyncTask 中覆盖的三个主要功能

  • doInBackground(Params...)
  • onProgressUpdate(Progress...)
  • onPostExecute(Result)

执行AsyncTask

使用要发送到后台任务的参数调用 execute()

发生了什么

  1. 在主/用户界面上,调用 onPreExecute() 。 (要在此线程中初始化某些内容,例如在用户界面上显示进度条。)

  2. 在后台主题中,调用 doInBackground(Params...) 。 (参数是传递给Execute函数的参数。)

    • 长期任务应该发生的地方

    • 必须至少覆盖doInBackground()才能使用AsyncTask。

    • 在后台计算仍在执行时,调用 publishProgress(Progress...) 更新用户界面中的进度显示。 (例如,为进度条设置动画或在文本字段中显示日志。)

      • 这会导致 onProgressUpdate() 被调用。
  3. 在后台线程中,从doInBackground()返回结果。这将触发下一步。

  4. 在主/用户界面上,使用返回的结果调用 onPostExecute()

  5. 实施例

    再次使用阻止任务的例子来从网上下载内容,

    • 示例A下载图像并将其显示在ImageView
    • 示例B下载一些文件

    示例A

    doInBackground()方法下载图像并将其存储在BitMap类型的对象中。 onPostExecute()方法获取位图并将其放在ImageView中。

    class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
        ImageView bitImage;
    
        public DownloadImageTask(ImageView bitImage) {
            this.bitImage = bitImage;
        }
    
        protected Bitmap doInBackground(String... urls) {
            String urldisplay = urls[0];
            Bitmap mBmp = null;
            try {
                InputStream in = new java.net.URL(urldisplay).openStream();
                mBmp = BitmapFactory.decodeStream(in);
            } catch (Exception e) {
                Log.e("Error", e.getMessage());
                e.printStackTrace();
            }
            return mBmp;
        }
    
        protected void onPostExecute(Bitmap result) {
            bitImage.setImageBitmap(result);
        }
    }
    

    例B

     private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
         protected Long doInBackground(URL... urls) {
             int count = urls.length;
             long totalSize = 0;
             for (int i = 0; i < count; i++) {
                 totalSize += Downloader.downloadFile(urls[i]);
                 publishProgress((int) ((i / (float) count) * 100));
                 // Escape early if cancel() is called
                 if (isCancelled()) break;
             }
             return totalSize;
         }
    
         protected void onProgressUpdate(Integer... progress) {
             setProgressPercent(progress[0]);
         }
    
         protected void onPostExecute(Long result) {
             showDialog("Downloaded " + result + " bytes");
         }
     }
    

    示例B执行

    new DownloadFilesTask().execute(url1, url2, url3);