源码解析-AsyncTask源码解析

新英格兰10机39节点matlab建模,ieee10机39节点系统数据 【实例简介】ieee10机39节点系统数据,主要是BPA数据!【实例截图】【核心代码】ne_039_bus└── ne_039_bus├── 039readme.doc├── bpa│ ├── 039bpa.dat│ ├── 039bpa.swi│ ├── LFerr.LIS│ ├── OneNote 目录.onetoc2│ └── STERR.LIS├── eurostag│... 阅读详情

在之前的博客,我们分析了Handler的源码,在我看来Handler的源码只要理清了流程还是比较简单的。而这次要讲解的AsyncTask的源码我自认为会比Handler稍微复杂一点,我们今天一起来了解一下。


在了解AsyncTask前,你需要先了解以下内容:

1.线程池

2.AsyncTask的基本使用的结构

3.Handler的基本使用


好,我们开始进入正题,还是拿我们之前举的那个例子

AsyncTask task = new AsyncTask<Void, Integer, Void>() {
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
            }
            protected void onProgressUpdate(Integer... values) {
                super.onProgressUpdate(values);
                if (isCancelled()) {
                    return;
                }
            }
 
            @Override
            protected Void doInBackground(Void... voids) {
                publishProgress();
                return null;
            }
 
            @Override
            protected void onPostExecute(Void aVoid) {
                super.onPostExecute(aVoid);
            }
 
            @Override
            protected void onCancelled() {
                super.onCancelled();
            }
        };

        task.execute();

这个是完整AsyncTask的使用的方式,但是实际上在我们创建AsyncTask中只需要重写一个doInBackground方法即可。其他的方法都可以不用重写。那么为什么这样呢?因为AsyncTask是一个抽象类,而他的抽象方法有且只有doInBackground这一个。所以更具抽象类实例化必须要实现他的抽象方法这个规则,所以我们只需要重写一个doInBackground方法。


好了简单的介绍了AsyncTask的使用之后,我们开始进入源码层面剖析AsyncTask。

回想一下,我们使用的AsyncTask的过程只需要创建一个AsyncTask的对象,重写他的子方法,然后启动这个AsyncTask就可以了,那么我们就根据这个流程来分析他的源码。


一、创建AsyncTask

一般我们在创建AsyncTask中使用的是下面的这个方法

    public AsyncTask() {
        this((Looper) null);
    }

而这个方法会调用另外一个构造器

 public AsyncTask(@Nullable Looper callbackLooper) {
        mHandler = callbackLooper == null || callbackLooper == Looper.getMainLooper()
            ? getMainHandler()
            : new Handler(callbackLooper);

        mWorker = new WorkerRunnable<Params, Result>() {
            public Result call() throws Exception {
                mTaskInvoked.set(true);
                Result result = null;
                try {
                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                    //noinspection unchecked
                    result = doInBackground(mParams);
                    Binder.flushPendingCommands();
                } catch (Throwable tr) {
                    mCancelled.set(true);
                    throw tr;
                } finally {
                    postResult(result);
                }
                return result;
            }
        };

        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 occurred while executing doInBackground()",
                            e.getCause());
                } catch (CancellationException e) {
                    postResultIfNotInvoked(null);
                }
            }
        };
    }

首先,这里先根据传入的 Looper 来创建一个Handler,这个mHandler在AsyncTask中至关重要,AsyncTask要把doinBackground中的执行结果传递给onPostExecute,即从后台运行耗时操作切换到ui线程,都是靠这个mHandler进行的线程的调度。

然后构造器里面又创建了两个对象,mWorker,mFuture。这两个对象也是非常重要的,下面我先简单的介绍一下。

mWorker的类型是WorkerRunnable,这个类很具有迷惑性,但是千万不要把它认作是执行一个后台操作的类,子线程只是调用了他的call方法。这个类的申明是在AsyncTask.java中的,是一个内部静态的抽象类。这个抽象类的构成很简单,我们可以从他的泛型中看出来,他的泛型一个是 mParams,传入之后作为一个变量保存。另一个Result即为call方法的回调,确定参数类型。

再看mFuture,它的类型是FutureTask,进入到这个类的源码,发现这个类实现了RunnableFuture接口。而这个借口又实现了Runnable接口,这个时候我们就知道了,真正执行线程方法的是这个类。这个类把上面的mWorker作为参数传进去了,又规定了一个泛型Result,定义了一个方法done()。

为了更好的理解AsyncTask的完整流程,在这一步中,我们暂时不进行call()与done()方法内容的讲解。至此第一步中的主要操作都在这里完成了。


第二步 实现AsyncTask的子方法

这一步很简单,也没有什么要详细说的。这里主要提一下各个方法,为第三步做铺垫。

AsyncTask可重写的方法 onPreExecute onProgressUpdate doInBackground  onPostExecute  onCancelled。

另外可在AsyncTask还有两个很重要的方法也在这里提一下,一个是 publishProgress(),一个是 cancel()。

具体这些方法是怎么工作的我们将会在第三步重点查看。


第三步 调用方法启动AsyncTask

在日常开发的过程中,我们常用 execute或者executeOnExecutor 来执行AsyncTask,这两个的区别是前者是使用一个叫sDefaultExecutor线程池,而后者用的是我们自定义的线程池

为了方便理解,我们先暂时不对sDefaultExecutor进行讲解,这个线程池我们将会在最后进行讲解

    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;
    }

我们暂时只看executeOnExecutor 方法,这里首先对本次AsyncTask的状态做了判断,根据抛出异常的msg,我们可以得出结论一个AsyncTask只能被启动一次。

接下来AsyncTask把自己的状态设置为正在运行,然后调用了onPreExecute()方法,此时我们的线程还未被切换,所以这里可以做一些线程未被切换的操作(因为一般传入的线程都是UI线程,所以这里的onPreExecute也是在UI线程中,onPreExecute常用于显示提示框之类)

然后程序把传入的参数复制给了mWorker这个对象中,然后调用了传入线程池的execute方法来执行线程(mFuture)。

接下来我们就得到Future这个类里面了,由于他被线程池所执行了,所以这里调用的是他的run方法。具体代码如下

 public void run() {
        if (state != NEW ||
            !U.compareAndSwapObject(this, RUNNER, null, Thread.currentThread()))
            return;
        try {
            Callable<V> c = callable;
            if (c != null && state == NEW) {
                V result;
                boolean ran;
                try {
                    result = c.call();
                    ran = true;
                } catch (Throwable ex) {
                    result = null;
                    ran = false;
                    setException(ex);
                }
                if (ran)
                    set(result);
            }
        } finally {
            runner = null;
            int s = state;
            if (s >= INTERRUPTING)
                handlePossibleCancellationInterrupt(s);
        }
    }

这里的代码也很清晰,首先先进行一次Future状态的判定。然后他会去取他的成员变量callable,这个callable我们可以从Future的构造器中得知就是之前我们在第一步中传入的mWork,他的泛型V就是我们所输出的结果的类型。接下来他就调用了callable的call方法,这时候我们再看一下第一步中我们暂时没有看的代码

mWorker = new WorkerRunnable<Params, Result>() {
            public Result call() throws Exception {
                mTaskInvoked.set(true);
                Result result = null;
                try {
                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                    //noinspection unchecked
                    result = doInBackground(mParams);
                    Binder.flushPendingCommands();
                } catch (Throwable tr) {
                    mCancelled.set(true);
                    throw tr;
                } finally {
                    postResult(result);
                }
                return result;
            }

这边我们重点要看的是 result = doInBackground(mParams)  这行代码,这里的mParams就是第三步一开始我们讲的那个 mWorker.mParams = params 赋值而来,而这个doInBackground对应的就是我们必须要重写doInBackground。这里一开始就讲了是启动了一个子线程,对应的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;
    }

可以看出来由于目前在子线程,这边使用了Handler进行线程间消息的通知,这个Handler就是我们第一步中创建的那个。而这个message的obj是创建出来的一个新的对象,这个对象把得到的结果存到了自己变量中。

这里要注意一下,这里涉及到了线程的切换,所以接下来我会分主线程以及线程池中的线程进行讲解

在主线程中

在主线程中,我们需要看一下handler中对应的方法。

 private static class InternalHandler extends Handler {
        public InternalHandler(Looper looper) {
            super(looper);
        }

        @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;
            }
        }
    }

这边采用了一个私有的内部静态类来申明了这个Handler。我们看一下对应的那个方法,很简单就是result.mTask.finish(result.mData[0]) 这么一行代码,这行代码要对应  Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,new AsyncTaskResult<Result>(this, result)) 一起看。

对应看我们就可以知道这个result.mTask.就是自己,所以我们继续找AsyncTask的finish这个方法。

    private void finish(Result result) {
        if (isCancelled()) {
            onCancelled(result);
        } else {
            onPostExecute(result);
        }
        mStatus = Status.FINISHED;
    }

这个方法很简单,先判断isCancelled,如果true,调用onCancelled方法,如果false调用onPostExecute方法,最后把AsyncTask的状态设置成finished。

这里我们关注一下isCancelled方法,他所关联的变量是 mCancelled ,我们看一下这个变量还有在哪里用到的。

   mWorker = new WorkerRunnable<Params, Result>() {
            public Result call() throws Exception {
                mTaskInvoked.set(true);
                Result result = null;
                try {
                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                    //noinspection unchecked
                    result = doInBackground(mParams);
                    Binder.flushPendingCommands();
                } catch (Throwable tr) {
                    mCancelled.set(true);
                    throw tr;
                } finally {
                    postResult(result);
                }
                return result;
            }
        };

    public final boolean isCancelled() {
        return mCancelled.get();
    }

    public final boolean cancel(boolean mayInterruptIfRunning) {
        mCancelled.set(true);
        return mFuture.cancel(mayInterruptIfRunning);
    }

从这个几个赋值的地方可以看出来被调用cancel方法和程序异常的时候,isCancelled的值为true。

其实到这里为止我们AsyncTask的流程大体上已经完成了,但是为了严谨我们还是把另外一部分给讲完。

子线程

 public void run() {
        if (state != NEW ||
            !U.compareAndSwapObject(this, RUNNER, null, Thread.currentThread()))
            return;
        try {
            Callable<V> c = callable;
            if (c != null && state == NEW) {
                V result;
                boolean ran;
                try {
                    result = c.call();
                    ran = true;
                } catch (Throwable ex) {
                    result = null;
                    ran = false;
                    setException(ex);
                }
                if (ran)
                    set(result);
            }
        } finally {
            // runner must be non-null until state is settled to
            // prevent concurrent calls to run()
            runner = null;
            // state must be re-read after nulling runner to prevent
            // leaked interrupts
            int s = state;
            if (s >= INTERRUPTING)
                handlePossibleCancellationInterrupt(s);
        }
    }

回到这里,执行完call方法的之后会调用set(result)方法,然后会执行以下流程

    protected void set(V v) {
        if (U.compareAndSwapInt(this, STATE, NEW, COMPLETING)) {
            outcome = v;
            U.putOrderedInt(this, STATE, NORMAL); // final state
            finishCompletion();
        }
    }

private void finishCompletion() {
        // assert state > COMPLETING;
        for (WaitNode q; (q = waiters) != null;) {
            if (U.compareAndSwapObject(this, WAITERS, q, null)) {
                for (;;) {
                    Thread t = q.thread;
                    if (t != null) {
                        q.thread = null;
                        LockSupport.unpark(t);
                    }
                    WaitNode next = q.next;
                    if (next == null)
                        break;
                    q.next = null; // unlink to help gc
                    q = next;
                }
                break;
            }
        }

        done();

        callable = null;        // to reduce footprint
    }

这两个方法最后调用done(),这个done方法对应的就是我们在初始化的时候创建的mFuture里面的done,代码如下

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 occurred while executing doInBackground()",
                            e.getCause());
                } catch (CancellationException e) {
                    postResultIfNotInvoked(null);
                }
            }
        };

    private void postResultIfNotInvoked(Result result) {
        final boolean wasTaskInvoked = mTaskInvoked.get();
        if (!wasTaskInvoked) {
            postResult(result);
        }
    }

乍一看代码,这里又postResult一遍,但是由于之前call方法中第一行就把这个值设成true,所以这个方法最后是不执行的。

讲到这里基本上已经把大部分的AsyncTask的流程都讲完了,接下来要讲的是 publishProgress 这个方法,让我们看一下源码

    protected final void publishProgress(Progress... values) {
        if (!isCancelled()) {
            getHandler().obtainMessage(MESSAGE_POST_PROGRESS,
                    new AsyncTaskResult<Progress>(this, values)).sendToTarget();
        }
    }

    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;
            }
    }

还是想handler发送了一条消息,然后handler取出他的mDate,也就是之前传入的values,调用AsyncTask的onProgressUpdate方法,这样publishProgress也就讲完了,那么整个AsyncTask的流程就讲完了。

写到这里感觉这篇文章有点过长了,太长的文章不仅作者写起来费劲,读者读起来也费尽。那么AsyncTask的总结与自身的默认线程池将放在下一篇博客中讲解=。=

 

 

 

基于matlab的CNN验证码识别系统(UI界面版) 基于matlab的CNN验证码识别系统(UI界面版),CNN验证码识别系统包括数据集处理、模型搭建、模型训练、界面设计与实现 阅读详情

相关推荐

PID不够用?试试用ADRC改造你的ArduCopter:从Simulink仿真到SITL测试全记录

本文详细介绍了如何将ADRC(自抗扰控制)算法集成到ArduPilot飞控中,以替代传统PID控制器。通过Simulink建模、参数整定和SITL仿真测试,展示了ADRC在抗扰动能力、响应速度和参数调节复杂度上的优势,特别适合无人机在强风扰动下的稳定控制。

weixin_32349093的博客 273

AsyncTask源码解析

AsyncTask (1)简介 一个Android已封装好的轻量级异步类,属于抽象类,使用时需要实现子类。用于 实现多线程,如在工作线程中执行耗时任务 异步通信、消息传递,如实现工作线程&主线程(UI线程)之间的通信,即:将工作线程的执行结果传递给主线程,从而在主线程中指向相关UI操作(保证线程安全) public abstract class AsyncTask<Params, Progress, Result> { ... } 不需使用"任务线程(如Thread类)+Han

莫言情怼的博客 369

centos7 python3.12.1 报错 No module named _ssl,坑我几个小时

网上的教程很多,但几乎是无效的,跟着我这教程,可以完美解决。

Amio_的博客 1万+

AsyncTask原理及不足

一 为什么需要工作者线程 Android应用的主线程(UI线程)肩负着绘制用户界面和及时响应用户操作的重任,为了避免”ANR”,就要确保主线程时刻保持较高的响应性.为了做到这一点,我们就要把耗时的任务移出主线程,那么耗时的任务交给谁来完成呢?答案就是工作者线程。Android开发中我们通常让主线程负责前台用户界面的绘制以及响应用户的操作,让工作者线程在后台执行一些比较耗时的任务。Android中的工作者线程主要有AsyncTask、IntentService、HandlerThread,它们本质上都是对线

qq_39431405的博客 639

Win11上从零跑通Carla自动驾驶仿真:保姆级环境配置与避坑指南(Python 3.7+)

本文详细介绍了在Win11系统上从零配置Carla自动驾驶仿真环境的完整流程,包括Python 3.7+环境搭建、依赖安装、常见问题排查及性能优化技巧。通过保姆级教程帮助开发者快速避坑,实现稳定的自动驾驶仿真测试环境部署。

weixin_33488239的博客 420

YOLOv5 自定义模型 Android 部署完整指南

本文详细介绍了将YOLOv5模型部署到Android设备的完整流程,包含三个核心部分:首先验证官方模型测试,确保基础环境配置正确;随后进行模型转换,从PyTorch导出ONNX格式并优化,再转换为NCNN格式;最后在Android项目中集成自定义模型,包括文件替换、参数修改和代码适配。教程基于YOLOv5 6.1版本,使用NCNN框架进行移动端推理,涵盖了常见问题解决方案和关键配置要点,为开发者提供了从训练到部署的完整技术路线。

FJN110的博客 591

AsyncTask的源码解读

一.概述AsyncTask就是一个封装了 Handler+线程池 的对象。 能够自由在主线程和子线程中来回切换 ----是串行执行任务的。二.基本概念CPU_COUNT = Runtime.getRunTime().getAvailableProcessors() --CPU核心数1. THREAD_POOL_EXECUTOR: 内部封装的一个线程池. 核心线程数:Math.max(2,Ma...

weixin_34024034的博客 156

结合MATLAB/Simulink和多体动力学仿真软件UM(Universal Mechanism),建立高速列车轴箱轴承的动力学模型,并通过联合仿真分析其正常运行特性和典型故障模式

高速列车是现代交通运输的重要组成部分,其运行速度高、载客量大,对安全性和可靠性提出了极高的要求。轴箱轴承作为高速列车的关键部件之一,承担着传递载荷和支撑车轴的重要作用。然而,由于长期运行在高速、重载和复杂工况下,轴箱轴承容易出现疲劳磨损、润滑失效和裂纹等故障,从而影响列车的安全性。本项目旨在结合MATLAB/Simulink和多体动力学仿真软件UM(Universal Mechanism),建立高速列车轴箱轴承的动力学模型,并通过联合仿真分析其正常运行特性和典型故障模式。

xiaoheshang_123的博客 329

AsyncTask异步消息处理机制

AsyncTask是一个抽象类,使用时必须创建一个子类继承它 其中,Parmas:启动任务执行的输入参数的类型,可用于后台任务中使用;     Progress:后台任务执行时,若需要在界面上显示进度,则使用这里指定的泛型作为进度单位;     Result:后台任务执行完成后返回的结果的类型。 启动方法:new Task().execute(); 需要重写的方法: onPre

rabbit_in_android的博客 678

量化 insider 爆料! 散户打板必亏?(打板必看!量化资金如何“隔日砸盘”收割散户)

量化开发 insider 爆料💥 散户追的涨停板📉,可能是机构故意做的陷阱!本文从技术视角拆解“涨停陷阱”,帮你看清市场真实逻辑🧠。

XiaoqiangClub的博客 450

Python爬虫实战:研究Pandas,构建车质网各车型数据采集和分析系统

研究结果表明,通过网络爬虫技术可以有效地获取公开的汽车投诉数据,这些数据经过适当的清洗和处理后,可以揭示出丰富的汽车质量信息。)作为国内专业的汽车质量投诉受理平台,自 2010 年成立以来,已累计接收消费者投诉信息超过 200 万条,这些数据包含了车型、投诉时间、投诉问题、处理状态等多维度信息,具有极高的分析价值。:通过对车质网数据的分析,能够挖掘出有价值的汽车质量信息,为消费者购车提供参考,为汽车厂商改进产品质量和服务提供依据,同时也能为相关监管部门提供数据支持。

ylfhpy的博客 937

Android AsyncTask 源码解析

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38614699,本文出自:【张鸿洋的博客】1、概述相信大家对AsyncTask都不陌生,对于执行耗时任务,然后更新UI是一把利器,当然也是替代Thread + Handler 的一种方式。如果你对Handler机制还不了解,请看:Android 异步消息处理机制 让你深入理解 Lo

Hongyang 3万+

群晖、飞牛NAS容器进入终端失败?一步步教你解决Docker Bash错误!(OCI runtime exec failed: exec failed)

群晖、飞牛NAS容器进入终端失败?一步步教你解决Docker Bash错误!(OCI runtime exec failed: exec failed)

XiaoqiangClub的博客 2991

Android AsyncTask源码解析

可以看到,这里先new出了一个SERIAL_EXECUTOR常量,然后将sDefaultExecutor的值赋值为这个常量,也就是说明,刚才在executeOnExecutor()方法中调用的execute()方法,其实也就是调用的SerialExecutor类中的execute()方法。这里我们模拟了一个下载任务,在doInBackground()方法中去执行具体的下载逻辑,在onProgressUpdate()方法中显示当前的下载进度,在onPostExecute()方法中来提示任务的执行结果。

jsjshshhshshhshw的博客 837

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Android源码探究之AsyncTask 源码解析

AsyncTask源码使用 Api23版本,后面介绍和以前版本改动不同之处。

李剑的博客 872

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

[Android] AsyncTask源码解析

常用例子 本文依照以下常用例子展开: private class DownloadFilesTask extends AsyncTask { protected Long doInBackground(URL... urls) { int count = urls.length; long totalSize = 0; for (int i

legendmohe的技术积累 842

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Android开发——AsyncTask的使用以及源码解析

1.AsyncTask使用介绍 AsyncTask封装了Thread和Handler,通过AsyncTask可以很方便地在执行完后台任务后更新UI。如果不太清楚Android的Handler机制,可以查看此篇Android消息机制详解。 下面是一个使用AsyncTask的实例,利用网络下载某URL里的字符串,以模拟耗时任务。在下载过程中,会通过进度条对话框向用户展示进度。在完成任务后将字...

关于Android开发的一些技术点总结 ╮( ̄▽ ̄”)╭ 1万+

Android AsyncTask完全解析,带你从源码的角度彻底理解

我们都知道,Android UI是线程不安全的,如果想要在子线程里进行UI操作,就需要借助Android的异步消息处理机制。之前我也写过了一篇文章从源码层面分析了Android的异步消息处理机制,感兴趣的朋友可以参考 Android Handler、Message完全解析,带你从源码的角度彻底理解 。 不过为了更加方便我们在子线程中更新UI元素,Android从1.5版本就引入了一个AsyncTask类,使用它就可以非常灵活地在UI线程和子线程之间自由切换。同时,它也是我们本篇文章的主角。 AsyncTas

郭霖的专栏 11万+
上一篇: Android基础-AsyncTask基本使用
下一篇: 源码解析-AsyncTask sDefaultExecutor解析
刘楼主
博客等级 码龄11年 8粉丝 39原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值