iis服务器助手广告广告
返回顶部
首页 > 资讯 > 移动开发 >Android AsyncTask实现机制详细介绍及实例代码
  • 267
分享到

Android AsyncTask实现机制详细介绍及实例代码

asynctaskAndroid 2022-06-06 05:06:21 267人浏览 安东尼
摘要

Android AsyncTask实现机制 示例代码: public final AsyncTask<Params, Progress, Result> exec

Android AsyncTask实现机制

示例代码:


public final AsyncTask<Params, Progress, Result> execute(Params... params) {
    return executeOnExecutor(sDefaultExecutor, params);
  }
  public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
      Params... params) {
    if (mStatus != Status.PENDING) {
      switch (mStatus) {
        case RUNNING:
          throw new IllegalStateException("Cannot execute task:"
              + " the task is already running.");
        case FINISHED:
          throw new IllegalStateException("Cannot execute task:"
              + " the task has already been executed "
              + "(a task can be executed only once)");
      }
    }
    mStatus = Status.RUNNING;
    onPreExecute();
    mWorker.mParams = params;
    exec.execute(mFuture);
    return this;
  }

execute先调用onPreExecute()(可见,onPreExecute是自动调用的)然后调用exec.execute(mFuture)


 public interface Executor {
    void execute(Runnable command);
  }

这是一个接口,具体实现在


 private static class SerialExecutor implements Executor {
    final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
    Runnable Mactive;
    public synchronized void execute(final Runnable r) {
      mTasks.offer(new Runnable() {
        public void run() {
          try {
            r.run();
          } finally {
            scheduleNext();
          }
        }
      });
      if (mActive == null) {
        scheduleNext();
      }
    }
    protected synchronized void scheduleNext() {
      if ((mActive = mTasks.poll()) != null) {
        THREAD_POOL_EXECUTOR.execute(mActive);
      }
    }
  }

从上面可知,AsyncTask执行过程如下:先执行onPreExecute,然后交给SerialExecutor执行。在SerialExecutor中,先把Runnable添加到mTasks中。

如果没有Runnable正在执行,那么就调用SerialExecutor的scheduleNext。同时当一个Runnable执行完以后,继续执行下一个任务

AsyncTask中有两个线程池,THREAD_POOL_EXECUTOR和SERIAL_EXECUTOR,以及一个Handler–InternalHandler


 
  public static final Executor THREAD_POOL_EXECUTOR
      = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
          TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
  
  public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
  private static InternalHandler sHandler;

SERIAL_EXECUTOR用于任务的排列,THREAD_POOL_EXECUTOR真正执行线程,InternalHandler用于线程切换
先看构造函数


  public AsyncTask() {
    mWorker = new WorkerRunnable<Params, Result>() {
      public Result call() throws Exception {
        mTaskInvoked.set(true);
        Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
        //noinspection unchecked
        return postResult(doInBackground(mParams));
      }
    };
    mFuture = new FutureTask<Result>(mWorker) {
      @Override
      protected void done() {
        try {
          postResultIfNotInvoked(get());
        } catch (InterruptedException e) {
          Android.util.Log.w(LOG_TAG, e);
        } catch (ExecutionException e) {
          throw new RuntimeException("An error occured while executing doInBackground()",
              e.getCause());
        } catch (CancellationException e) {
          postResultIfNotInvoked(null);
        }
      }
    };
  }

看到了熟悉的doInBackground了吧,然后调用postResult


 private Result postResult(Result result) {
    @SuppressWarnings("unchecked")
    Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
        new AsyncTaskResult<Result>(this, result));
    message.sendToTarget();
    return result;
  }

主线程中创建InternalHandler并发送MESSAGE_POST_RESULT消息,然后调用finish函数


 private static class InternalHandler extends Handler {
    public InternalHandler() {
      super(Looper.getMainLooper());
    }
    @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
    @Override
    public void handleMessage(Message msg) {
      AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;
      switch (msg.what) {
        case MESSAGE_POST_RESULT:
          // There is only one result
          result.mTask.finish(result.mData[0]);
          break;
        case MESSAGE_POST_PROGRESS:
          result.mTask.onProgressUpdate(result.mData);
          break;
      }
    }
  }
  private void finish(Result result) {
    if (isCancelled()) {
      onCancelled(result);
    } else {
      onPostExecute(result);
    }
    mStatus = Status.FINISHED;
  }

finish中调用onPostExecute。

AsyncTask工作流程:new MyThread().execute(1);

先构造函数,然后execute

构造函数只是准备了mWorker和mFuture这两个变量

execute中调用onPreExecute,然后exec.execute(mFuture),其中响应了call函数,call中调用doInBackground,然后将结果传给Handler然后finish掉,finish函数调用onPostExecute

你可能会奇怪,为什么没有onProgressUpdate,有注解可以解释


 
  @SuppressWarnings({"UnusedDeclaration"})
  protected void onProgressUpdate(Progress... values) {
  }

也就是说必须调用publishProgress才会自动调用onProgressUpdate。
那如何调用publishProgress呢?


 
  protected abstract Result doInBackground(Params... params);

doInBackground说的很明确,在doInBackground函数里面显示调用publishProgress即可。

publishProgress源码


 protected final void publishProgress(Progress... values) {
    if (!isCancelled()) {
      getHandler().obtainMessage(MESSAGE_POST_PROGRESS,
          new AsyncTaskResult<Progress>(this, values)).sendToTarget();
    }
  }
  private static class InternalHandler extends Handler {
    public InternalHandler() {
      super(Looper.getMainLooper());
    }
    @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
    @Override
    public void handleMessage(Message msg) {
      AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;
      switch (msg.what) {
        case MESSAGE_POST_RESULT:
          // There is only one result
          result.mTask.finish(result.mData[0]);
          break;
        case MESSAGE_POST_PROGRESS:
          //****************************************在这里调用
          result.mTask.onProgressUpdate(result.mData);
          break;
      }
    }
  }

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

您可能感兴趣的文章:Android带进度条的文件上传示例(使用AsyncTask异步任务)Android中通过AsyncTask类来制作炫酷进度条的实例教程Android AsyncTask用法巧用实例代码Android屏幕旋转 处理Activity与AsyncTask的最佳解决方案Android中使用AsyncTask实现文件下载以及进度更新提示详解Android App中的AsyncTask异步任务执行方式Android AsyncTask完全解析 带你从源码的角度彻底理解Android AsyncTask源码分析Android中使用AsyncTask做下载进度条实例代码


--结束END--

本文标题: Android AsyncTask实现机制详细介绍及实例代码

本文链接: https://www.lsjlt.com/news/22874.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • SpringBoot详细介绍SPI机制示例
    目录简介Java SPI实现示例说明创建动态接口实现类1实现类2相关测试运行结果源码分析Spring SPI源码分析总结简介 SPI(Service Provider Interfa...
    99+
    2024-04-02
  • Android ViewPagerIndicator详解及实例代码
    Android ViewPagerIndicator详解及实例代码关于自定义View的属性零碎知识自定义View和自定义属性的知识不再此提及,这里着重说的是属性在自定义View中的获取方式,自定义的属性如下:<?xml ver...
    99+
    2023-05-31
    android viewpagerindicator age
  • C++实现三子棋游戏详细介绍(附代码)
    目录游戏描述:游戏思维导图:(从头开始)头文件也写在前面:先把游戏与主函数写在前面:游戏函数:主函数:1.构建游戏菜单2.构建棋盘3.玩家和电脑下棋3.1玩家先下3.2电脑下棋4.判...
    99+
    2024-04-02
  • Go语言同步机制解析:详细介绍与应用实例
    请稍等,我来为您创作这篇文章。以上就是Go语言同步机制解析:详细介绍与应用实例的详细内容,更多请关注编程网其它相关文章! ...
    99+
    2024-03-01
    go语言 应用实例 同步机制
  • redis锁机制介绍与实例
    1 悲观锁 执行操作前假设当前的操作肯定(或有很大几率)会被打断(悲观)。基于这个假设,我们在做操作前就会把相关资源锁定,不允许自己执行期间有其他操作干扰。 Redis不支持悲观锁。Redis作为缓存服务器...
    99+
    2024-04-02
  • PythonCountingBloomFilter原理与实现详细介绍
    目录前言原理一、BF 为什么不支持删除二、什么是 Counting Bloom Filter三、Counter 大小的选择简单的实现总结前言 标准的 Bloom Filter 是一种...
    99+
    2024-04-02
  • Android实现webview实例代码
    webview是一个很简单的功能,代码没有什么逻辑上的难度,只是需要注意权限上的问题。其实在安卓编程的过程当中,权限问题可以算是出现的比较多的BUG。MainActpackage com.lxq.webview01;import andro...
    99+
    2023-05-31
    android webview roi
  • AJAX实现鼠标经过弹出详细介绍示例
    复制代码 代码如下: <span style="font-size:14px;"><script type="text/javascript"> var ep...
    99+
    2022-11-15
    AJAX 鼠标经过 弹出
  • Spring的Ioc模拟实现详细介绍
    简单来说就是当自己需要一个对象的时候不需要自己手动去new一个,而是由其他容器来帮你提供;Spring里面就是IOC容器。例如:在Spring里面经常需要在Service这个装配一个Dao,一般是使用@Autowired注解:类似如下pub...
    99+
    2023-05-30
    spring ioc sprin
  • JVM类加载机制及生命周期的详细介绍
    这篇文章主要讲解了“JVM类加载机制及生命周期的详细介绍”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JVM类加载机制及生命周期的详细介绍”吧!一.目标:什么是类的加载?类的生命周期?类加载...
    99+
    2023-06-02
  • Kotlin类的继承实现详细介绍
    1.在kotlin中,默认类都是封闭的closed的。如果要让某个类开放继承,必须用open关键字修饰 类中的方法默认也是关闭的。如果需要子类复写父类的方法,也必须用open修饰。 ...
    99+
    2024-04-02
  • C++实现关机功能详细代码
    目录前言:功能实现:总结前言: 可以写出来后发给你的室友或者好朋友,可以增进你们之间的友谊 功能实现: 输入关机命令语句,shutdown -s -t 60,电脑就会在60秒之后关机...
    99+
    2024-04-02
  • Android实现绘制LocationMarkerView图的示例代码
    目录LocationMarkerView图的绘制绘制整公里的文字添加动画LocationMarker是运动轨迹上Start、End, 以及整公里点上笔者自定义绘制的一个MarkerV...
    99+
    2023-02-10
    Android绘制LocationMarkerView图 Android LocationMarkerView图 Android LocationMarkerView
  • Android IPC机制Messenger实例详解
    Android IPC机制Messenger实例详解前言:Messenger可以翻译成信使,通过它可以在不同进程间传递Message对象有了它就可以轻松实现进程间的数据传递了。Messenger使用的方法相对AIDL比较简单,它对AIDL做...
    99+
    2023-05-30
    android ipc机制 messenger
  • Android绘制验证码的实例代码
    在前面仿华为加载动画、仿网易音乐听歌识曲-麦克风动画中,我们通过绘图的基础知识完成了简单的绘制。在本例中,我们将绘制常见的验证码。一、效果图二、知识点与思路分析通过上面的效果图观察,我们可以看到里面有绘制的随机线条,随机绘制的验证码。绘制线...
    99+
    2023-05-31
    android 验证码 roi
  • Android中实现视差滚动示例介绍
    什么是视差滚动? 视差滚动原本是一个天文学术语,当我们观察星空的时候,离我们比较远的星星移动速度比较慢,离我们比较近的星星移动速度比较快,当我们坐在车上向车窗外看的时候也会有这种体验...
    99+
    2024-04-02
  • 详解pytest实现mark标记功能详细介绍
    mark标记 ​在实际工作中,我们要写的自动化用例会比较多,也不会都放在一个py文件中,如果有几十个py文件,上百个方法,而我们只想运行当中部分的用例时怎么办? R...
    99+
    2024-04-02
  • Vue3+Vite实现动态路由的详细实例代码
    项目基本目录 1.首先定义初始默认的路由routes(router.js文件),vue文件使用import引入可以按需加载 import { createRouter, ...
    99+
    2024-04-02
  • 阿里云RDS数据库实例的详细介绍
    阿里云RDS是阿里云提供的关系型数据库服务,它可以帮助用户快速搭建和管理数据库实例,提供稳定、安全、高效的数据存储和处理能力。在本文中,我们将详细介绍阿里云RDS数据库实例的特性和使用方法。 一、阿里云RDS的优势架构简单:阿里云RDS提供...
    99+
    2023-11-07
    阿里 详细介绍 实例
  • 详细介绍如何使用手机下载Gitee上的代码
    在移动互联网时代,我们不再局限于使用电脑进行编程,手机也可以成为我们进行代码管理与开发的利器。而作为国内著名的代码托管平台,Gitee也提供了在手机上下载代码的功能。本文将详细介绍如何使用手机下载Gitee上的代码。一、前置条件在使用Git...
    99+
    2023-10-22
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作