最新AsyncTask源码分析(1),附超全教程文档

最后

看完上述知识点如果你深感Java基础不够扎实,或者刷题刷的不够、知识不全面

小编专门为你量身定制了一套<Java一线大厂高岗面试题解析合集:JAVA基础-中级-高级面试+SSM框架+分布式+性能调优+微服务+并发编程+网络+设计模式+数据结构与算法>

image

针对知识面不够,也莫慌!还有一整套的<Java核心进阶手册>,可以瞬间查漏补缺

image

全都是一丢一丢的收集整理纯手打出来的

更有纯手绘的各大知识体系大纲,可供梳理:Java筑基、MySQL、Redis、并发编程、Spring、分布式高性能架构知识、微服务架构知识、开源框架知识点等等的xmind手绘图~

image

image

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

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(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);

}

}

};

}

  • 我们先来分析一下mWorker;

mWorker为AsyncTask的一个内部类

,实现了Callable接口,在call方法里面会调用我们的doInBackground方法,这也就是为什么我们的doInBackground。方法是在子线程里面执行的,执行完doInBackground()方法会把结构传递给我们的postResult(result)方法,在result方法,会调用handler发送消息,

接着再handler的handleMessage里面处理,在handleMessage里面,又会调用我们的 finish()方法,finish()方法里面会判断任务是否取消,如果被取消,会调用onCancelled(),否则会调用onPostExecute()方法。

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;

}

  • 接着我们来分析一下mFuture

mFuture = new FutureTask(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);

}

}

};

  1. postResultIfNotInvoked(get());get()表示获取mWorker的call的返回值,即Result。

  2. 然后看postResultIfNotInvoked方法。会判断是否已经将结果发送出去,即判断在mWork里面是否已经调用postResult(result)发送结果,没有的话调用再调用postResult(result)发送出去

private void postResultIfNotInvoked(Result result) {

final boolean wasTaskInvoked = mTaskInvoked.get();

if (!wasTaskInvoked) {

postResult(result);

}

}

还记得上面exec.execute()吗?exec为executeOnExecutor(sDefaultExecutor,params)中的sDefaultExecutor

下面看这个sDefaultExecutor

private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;

public static final Executor SERIAL_EXECUTOR = new SerialExecutor();

private static class SerialExecutor implements Executor {

final ArrayDeque mTasks = new ArrayDeque();

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

}

}

}

可以看到sDefaultExecutor其实为SerialExecutor的一个实例,其内部维持一个任务队列;直接看其execute(Runnable runnable)方法,将runnable放入mTasks队尾;

判断当前mActive是否为空,为空则调用scheduleNext方法

scheduleNext方法里面,则直接取出任务队列中的队首任务,如果不为null则传入THREAD_POOL_EXECUTOR进行执行。

下面看THREAD_POOL_EXECUTOR为何方神圣:

Public static final Executor THREAD_POOL_EXECUTOR

=new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,

TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);

可以看到就是一个自己设置参数的线程池,参数为:

private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));

private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;

private static final int KEEP_ALIVE_SECONDS = 30;

private static final ThreadFactory sThreadFactory = new ThreadFactory() {

private final AtomicInteger mCount = new AtomicInteger(1);

public Thread newThread(Runnable r) {

return new Thread(r, “AsyncTask #” + mCount.getAndIncrement());

}

};

private static final BlockingQueue sPoolWorkQueue =

new LinkedBlockingQueue(128);

回顾一下sDefaultExecutor,真正在execute()中调用的为sDefaultExecutor.execute:

private static class SerialExecutor implements Executor {

final ArrayDeque mTasks = new ArrayDeque();

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

}

}

}

可以看到,如果此时有10个任务同时调用execute(s synchronized)方法,第一个任务入队,然后在mActive = mTasks.poll()) != null被取出,并且赋值给mActivte,然后交给线程池去执行。然后第二个任务入队,但是此时mActive并不为null,并不会执行scheduleNext();所以如果第一个任务比较慢,10个任务都会进入队列等待;

真正执行下一个任务的时机是,线程池执行完成第一个任务以后,调用Runnable中的finally代码块中的scheduleNext,所以虽然内部有一个线程池,其实调用的过程还是线性的。一个接着一个的执行,相当于单线程。

publicProgress()方法的分析

这也就是我们在Result doInBackground(Params… params)方法里面调用 publishProgress()方法,会回调onProgressUpdate的原因

protected final void publishProgress(Progress… values) {

if (!isCancelled()) {

getHandler().obtainMessage(MESSAGE_POST_PROGRESS,

new AsyncTaskResult(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;

最后

分享一些资料给大家,我觉得这些都是很有用的东西,大家也可以跟着来学习,查漏补缺。

《Java高级面试》

《Java高级架构知识》

《算法知识》

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

sult.mTask.finish(result.mData[0]);

break;

最后

分享一些资料给大家,我觉得这些都是很有用的东西,大家也可以跟着来学习,查漏补缺。

《Java高级面试》

[外链图片转存中…(img-xVPK2nEt-1715624445862)]

《Java高级架构知识》

[外链图片转存中…(img-0YjCV6V6-1715624445863)]

《算法知识》

[外链图片转存中…(img-XsBK8Ri8-1715624445863)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 9
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android网络连接源码分析主要涉及到Android系统中网络连接的相关实现和机制。下面是Android网络连接的源码分析: 1. 网络连接管理类:Android中的网络连接管理由ConnectivityManager类负责。该类提供了获取网络状态、监听网络状态变化等功能。其源码位于frameworks/base/core/java/android/net/ConnectivityManager.java。 2. 网络请求类:Android中的网络请求由HttpClient或HttpURLConnection实现。在Android 6.0及以上版本中,Google推荐使用HttpURLConnection。HttpClient的源码位于frameworks/base/core/java/org/apache/http/impl/client/DefaultHttpClient.java,HttpURLConnection的源码位于libcore/luni/src/main/java/java/net/HttpURLConnection.java。 3. 网络请求处理类:Android中的网络请求处理由AsyncTask或者Thread实现。AsyncTask是一个封装了线程池和Handler的异步任务类,用于在后台执行耗时操作,并在主线程更新UI。其源码位于frameworks/base/core/java/android/os/AsyncTask.java。 4. 网络请求结果处理类:Android中的网络请求结果处理由Handler或者Callback实现。Handler用于在主线程中处理异步任务的结果,Callback则是一种回调机制,用于在异步任务完成后执行相应的操作。 5. 网络缓存类:Android中的网络缓存由DiskLruCache或者LruCache实现。DiskLruCache用于将网络请求结果缓存到本地磁盘,LruCache则是一种内存缓存机制,用于缓存网络请求结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值