线程在android是个重要的概念,从用途上讲,线程分为主线程和子线程,主线程负责页面相关,子线程负责耗时操作。

在android中除了Thread本身还有 AsyncTask  IntentService  HandlerThread。

AsyncTask

  1. public abstract class AsyncTask<Params, Progress, Result>

1 Params 参数类型
2 Progress 执行进度类型
3 Result 返回数据类型

不需要参数可以用Void代替

它提供了4个核心方法:

  1. //异步任务执行之前调用,一般用来执行一些准备操作
  2. @Override
  3. protected void onPreExecute() {
  4. super.onPreExecute();
  5. }
  6. //在线程池调用, 用于执行异步任务
  7. @Override
  8. protected String doInBackground(String... params) {
  9. return null;
  10. }
  11. //异步任务执行之后会调用
  12. @Override
  13. protected void onPostExecute(String result) {
  14. super.onPostExecute(result);
  15. }
  16. //主线程中执行,后台任务执行进度发生改变调用
  17. @Override
  18. protected void onProgressUpdate(Void... values) {
  19. super.onProgressUpdate(values);
  20. }

注意:

1 AsyncTask类必须在主线程中加载

2 AsyncTask的对象必须在主线程创建

3 execute必须在UI线程调用

4 一个AsyncTask的对象只能执行一次,即只调用一次execute方法

工作原理:

  1. public final AsyncTask<Params, Progress, Result> execute(Params... params) {
  2. return executeOnExecutor(sDefaultExecutor, params);
  3. }
  4. execute 方法会调用 executeOnExecutor 方法;看一下 executeOnExecutor 方法:
  5. public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
  6. Params... params) {
  7. if (mStatus != Status.PENDING) {
  8. switch (mStatus) {
  9. case RUNNING:
  10. throw new IllegalStateException("Cannot execute task:"
  11. + " the task is already running.");
  12. case FINISHED:
  13. throw new IllegalStateException("Cannot execute task:"
  14. + " the task has already been executed "
  15. + "(a task can be executed only once)");
  16. }
  17. }
  18.  
  19. mStatus = Status.RUNNING;
  20.  
  21. onPreExecute();
  22.  
  23. mWorker.mParams = params;
  24. exec.execute(mFuture);
  25.  
  26. return this;
  27. }

可以看出封装了一个线程池,接着找我发现了

  1. private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
  2. public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
  3.  
  4. private static class SerialExecutor implements Executor {
  5. final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
  6. Runnable mActive;
  7.  
  8. public synchronized void execute(final Runnable r) {
  9. mTasks.offer(new Runnable() {
  10. public void run() {
  11. try {
  12. r.run();
  13. } finally {
  14. scheduleNext();
  15. }
  16. }
  17. });
  18. if (mActive == null) {
  19. scheduleNext();
  20. }
  21. }

从SerialExecutor 看出AsyncTask是排队执行的过程。

系统首先会把AsyncTask的参数Params 封装为FutureTask对象,接着会把FutureTask交给SerialExecutor的execute处理,
execute方法把FutureTask交给mTasks任务队列中,如果这时没有AsyncTask任务,SerialExecutor会
scheduleNext()来执行下一个任务。当一个任务执行完以后,SerialExecutor才会执行其他任务,可以看出AsyncTask是串
行的。

AsyncTask构造函数有这样一段代码:

  1. mWorker = new WorkerRunnable<Params, Result>() {
  2. public Result call() throws Exception {
  3. mTaskInvoked.set(true);
  4.  
  5. Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
  6. //noinspection unchecked
  7. return postResult(doInBackground(mParams));
  8. }
  9. };

再看FutureTask的run方法:

  1. 派生到我的代码片
  2.  
  3. public void run() {
  4. if (state != NEW ||
  5. !UNSAFE.compareAndSwapObject(this, runnerOffset,
  6. null, Thread.currentThread()))
  7. return;
  8. try {
  9. Callable<V> c = callable;
  10. if (c != null && state == NEW) {
  11. V result;
  12. boolean ran;
  13. try {
  14. result = c.call();
  15. ran = true;
  16. } catch (Throwable ex) {
  17. result = null;
  18. ran = false;
  19. setException(ex);
  20. }
  21. if (ran)
  22. set(result);
  23. }
  24. } finally {
  25. // runner must be non-null until state is settled to
  26. // prevent concurrent calls to run()
  27. runner = null;
  28. // state must be re-read after nulling runner to prevent
  29. // leaked interrupts
  30. int s = state;
  31. if (s >= INTERRUPTING)
  32. handlePossibleCancellationInterrupt(s);
  33. }
  34. }

发现FutureTask的run方法是执行了mWorker的call的,所以call也会在线程池中执行。

mWorker的call中将mTaskInvoked.set(true);表示当前任务已经调用然后执行AsyncTask的doInBackground方法接着将
返回值传给postResult方法;

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

可以看出postResult通过一个Handler发送一个MESSAGE_POST_RESULT消息

  1. private static Handler getHandler() {
  2. synchronized (AsyncTask.class) {
  3. if (sHandler == null) {
  4. sHandler = new InternalHandler();
  5. }
  6. return sHandler;
  7. }
  8. }
  9.  
  10. private static class InternalHandler extends Handler {
  11. public InternalHandler() {
  12. super(Looper.getMainLooper());
  13. }
  14.  
  15. @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
  16. @Override
  17. public void handleMessage(Message msg) {
  18. AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;
  19. switch (msg.what) {
  20. case MESSAGE_POST_RESULT:
  21. // There is only one result
  22. result.mTask.finish(result.mData[0]);
  23. break;
  24. case MESSAGE_POST_PROGRESS:
  25. result.mTask.onProgressUpdate(result.mData);
  26. break;
  27. }
  28. }
  29. }

当这个Handler收到MESSAGE_POST_RESULT消息之后,会调用finish方法了

  1. private void finish(Result result) {
  2. if (isCancelled()) {
  3. onCancelled(result);
  4. } else {
  5. onPostExecute(result);
  6. }
  7. mStatus = Status.FINISHED;
  8. }

如果取消执行就 onCancelled 了,否则就调用onPostExecute这个方法。

android线程与线程池-----AsyncTask(一)《android开发艺术与探索》的更多相关文章

  1. android线程与线程池-----线程池(二)《android开发艺术与探索》

    android 中的线程池 线程池的优点: 1 重用线程池中的线程,避免了线程的创建和销毁带来的性能开销 2 能有效的控制最大并发数,避免大量线程之间因为喜欢抢资源而导致阻塞 3 能够对线程进行简单的 ...

  2. 踏破铁鞋无觅处,从AsyncTask学Android线程池

    android对于主线程的响应时间限制的非常严格,稍有不慎就会遇到Application Not Responding(ANR)的弹框.用户可以轻点手指关掉你的APP.官方文档写的非常明确!同时,保持 ...

  3. 《Android开发艺术探索》读书笔记 (11) 第11章 Android的线程和线程池

    第11章 Android的线程和线程池 11.1 主线程和子线程 (1)在Java中默认情况下一个进程只有一个线程,也就是主线程,其他线程都是子线程,也叫工作线程.Android中的主线程主要处理和界 ...

  4. android中对线程池的理解与使用

    前段时间有幸接到腾讯上海分公司的 Android开发面试,虽然最后一轮被毙了.但还是得总结一下自己在android开发中的一些盲点,最让我尴尬的是面试官问我几个android中线程池的使用与理解..哎 ...

  5. Android的线程和线程池

    ---恢复内容开始--- 一.Android线程的形态 (一)AsyncTask解析 AysncTask简介:①.实现上封装了Thread和Handler   ②.不适合进行特别耗时的后台任务 Ays ...

  6. 《android开发艺术探索》读书笔记(十一)--Android的线程和线程池

    接上篇<android开发艺术探索>读书笔记(十)--Android的消息机制 No1: 在Android中可以扮演线程角色的有很多,比如AsyncTask.IntentService.H ...

  7. 《Android开发艺术探索》第11章 Android的线程和线程池

    第11章 Android的线程和线程池 11.1 主线程和子线程 (1)在Java中默认情况下一个进程只有一个线程,也就是主线程,其他线程都是子线程,也叫工作线程.Android中的主线程主要处理和界 ...

  8. Android中线程和线程池

    我们知道线程是CPU调度的最小单位.在Android中主线程是不能够做耗时操作的,子线程是不能够更新UI的.在Android中,除了Thread外,扮演线程的角色有很多,如AsyncTask,Inte ...

  9. android线程 Handler Message Queue AsyncTask线程模型 线程交互 + 修改Button样式 示例 最终easy整合版

     首先原谅我把文章的标题写的这么长.其实我还嫌弃它短了因为 写不下去了所以我就不写了.因为我实在不知道该怎么定义这篇文章的标题或许应该叫 "乱谈"比较合适. 这样可能还体现了 ...

随机推荐

  1. Seattle(65) lypzxy的博客

    http://www.cnblogs.com/cb168/tag/Firemonkey/

  2. Windows读取文本文件后的显示过程

    Windows首先将文本数据转换到它内部使用的编码格式:Unicode,然后按照文本的Unicode去字体文件中查找字体图像,最后将图像显示到窗口上. 总结一下前面的分析,文字的显示应该是这样的: 步 ...

  3. 用sql增、修改、删除字段

    --给一个表增加一个字段 ); --给一个表修改一个字段的数据类型 ,); --通用sql修改字段的用法 ,); --删除一个字段 alter table wm_goods drop column b ...

  4. 深入浅出 - Android系统移植与平台开发(十)- Android编译系统与定制Android平台系统(瘋耔修改篇二)

    第四章.Android编译系统与定制Android平台系统 4.1Android编译系统 Android的源码由几十万个文件构成,这些文件之间有的相互依赖,有的又相互独立,它们按功能或类型又被放到不同 ...

  5. minicom-2.4安装配置

    minicom-2.4安装说明 1.#tar –zxvf minicom-2.4.tar.gz 解压开有连个文件,minicom-2[1].4.tar.gz  和minirc.dfl rpm包方式# ...

  6. (转载)C++中, 构造函数和析构函数能不能被显示调用?

    (转载)http://blog.csdn.net/zhangxinrun/article/details/6056321 代码: view plaincopy to clipboardprint?#i ...

  7. C# Sending data using GET or POST ZZ

    In this short article, I'll show you how to send data to a website from a C# application using GET o ...

  8. Delphi 继承基类的窗体,并显示基类的控件操作。

    1.  先建一个普通的窗体,until1 2.  先把类实现基类, 并需要实现基类需要继承的方法, 可以先不用再方法中写实现代码. TForm4 = class(TfrmmtAReportPeriod ...

  9. Uninstall Tool 3.3.2.5315 简体中文注册版(彻底卸载软件)

    Uninstall Tool Uninstall Tool是CrystalIdea Software出品的一款强大而灵活的Windows标准“添加/删除程序”工具的替代软件.它能快速,安全而方便的删除 ...

  10. Windows 8 Hyper-V虚拟机功能(转载)

    刚才看见一兄弟w500折腾win8 hyper-v功能,普及下吧,欢迎各位斧正 Windows 8 中 Hyper-V 3.0 的 CPU 支持说明 Windows 8 将直接内置 Hyper-V 3 ...