目录
1、背景
在Android中,除了Thread扮演线程角色以外,还有AsyncTask、HandlerThread、IntentService同样可以担当起异步线程的任务,它们各自有自己的适用场景。
AsyncTask:封装了Handler和线程池,它主要是为了方便开发者在子线程中更新UI;
HandlerThread:简化了我们创建子线程Handler的过程,简化我们线程间消息传递的过程;
IntentService:内部使用了HandlerThread,它相当于一个后台线程,单相对于Thread来说,它继承了四大组件Service,所以它的优先级会高点,不容易被系统杀死。很适合后台下载类似的任务。
2、简介
AsyncTask是一个轻量级的异步任务类,它可以在线程池中执行后台任务,然后把执行任务的进度和结果传递给主线程,并在主线程中进行更新UI的操作。
AsyncTask内部实现:使用线程池来执行异步任务,然后通过Handler来将异步任务的结果,推送到我们的UI线程。
注意:AysncTask并不适合执行一些特别耗时的操作,对于特别耗时的任务,建议使用线程池。
2.1、详解
AsyncTask是一个抽象的范型类。
Params:表示参数的类型;
Progres:表示后台任务的执行进度的类型;
Result:表示后台任务返回的结果。
Async提供了四个主要的方法。除了doInBackground()方法在异步线程外,其他的三个方法都在主线程中。
2.2、使用
这里我们继承实现了AsyncTask,然后传入1、2、3三个int值,然后在异步线程池中进行相加,并且每次睡眠3秒,最后将和传到我们的UI线程,看最后的输出结果,我们也能看到只有doInBackground()在异步的线程池中执行。其余的方法都在UI线程中。
-
public
class Test_My_AsyncTask extends AsyncTask<Integer, Integer, String> {
-
-
@Override
-
protected void onPreExecute() {
-
super.onPreExecute();
-
log(
"onPreExecute.准备");
-
}
-
-
@Override
-
protected String doInBackground(Integer... integers) {
-
-
int add =
0;
-
for (Integer i : integers) {
-
publishProgress(i);
-
try {
-
Thread.sleep(
3000);
-
}
catch (InterruptedException e) {
-
e.printStackTrace();
-
}
-
-
add = add + i;
-
log(
"doInBackground.add=" + add);
-
}
-
-
String result =
"参数之和=" + add;
-
-
return result;
-
}
-
-
@Override
-
protected void onProgressUpdate(Integer... values) {
-
super.onProgressUpdate(values);
-
for (Integer i : values) {
-
log(
"onProgressUpdate.进度:" + i);
-
}
-
}
-
-
@Override
-
protected void onPostExecute(String s) {
-
super.onPostExecute(s);
-
log(
"onPostExecute.结果:" + s);
-
}
-
-
-
private void log(String msg) {
-
Log.e(
"Test_AsyncTask",String.format(
"%tr",
new Date()) +
": "
-
+ Thread.currentThread().getName() +
": " + msg);
-
}
-
}
-
-
----------------------调用---------------------------------
-
Test_AsyncTask test =
new Test_AsyncTask()
-
test.execute(
1,
2,
3)
-
-
-----------------------结果---------------------------------
-
3、源码详解
从上面的使用来看,我们运行Test_My_AsyncTask的时候,只需要new出来Test_My_AsyncTask对象,然后执行它的execute()方法。
那么我们首先看一下AsyncTask的构造函数都做了什么操作?
3.1、new AsyncTask()
看下图:
当我们new 一个AsyncTask对象的时候:
1、我们会创建一个主线程的Handler;
2、我们的doInBackground()函数会被放在一个类似线程的执行对象Runnable中;
3、然后我们的doInBackground()函数返回的结果会通过Handler发送到主线程中,并且调用onPostExecute()函数。
4、当然到现在,onPostExecute()还没有被执行,因为我们还没有diao
注意:如果你想要了解Callback 和FutureTask,可以进入这个连接了解一下,如果不想了解,可以把它们当成Runnable也行。
3.2、execute()
execute()的执行:
1、会先调用onPreExecute();
2、sDefaultExecutor线程池会执行我们前面类似Runnable的FutureTask对象,这样就会执行doInBackground()方法。
3、而且在sDefaultExecutor线程池中,我们的doInBackground()并没有执行,只是被添加到一个ArrayDeque中,真正执行该任务的是THREAD_POOL_EXECUTOR线程池。
4、这样我们整个流程就算完成了。
注意:从ArrayDeque来看,默认情况,我们的AsyncTask是串行执行的。
4、手写代码
Async类
-
package com.yobo.yo_android.test_AsyncTask;
-
-
import android.os.Handler;
-
import android.os.Looper;
-
import android.os.Message;
-
-
import java.util.ArrayDeque;
-
import java.util.concurrent.BlockingQueue;
-
import java.util.concurrent.Callable;
-
import java.util.concurrent.ExecutionException;
-
import java.util.concurrent.Executor;
-
import java.util.concurrent.FutureTask;
-
import java.util.concurrent.LinkedBlockingQueue;
-
import java.util.concurrent.ThreadFactory;
-
import java.util.concurrent.ThreadPoolExecutor;
-
import java.util.concurrent.TimeUnit;
-
import java.util.concurrent.atomic.AtomicBoolean;
-
import java.util.concurrent.atomic.AtomicInteger;
-
-
-
public
abstract
class AsyncTask<Params, Progress, Result> {
-
-
private
static
final
int MESSAGE_POST_RESULT =
0x1;
-
private
static
final
int MESSAGE_POST_PROGRESS =
0x2;
-
-
private
final WorkerRunnable<Params, Result> mWorker;
-
private
final FutureTask<Result> mFuture;
-
private
final Handler mHandler;
-
-
private
final AtomicBoolean mTaskInvoked =
new AtomicBoolean();
-
-
public AsyncTask() {
-
-
mHandler =
new InternalHandler(Looper.getMainLooper());
-
-
mWorker =
new WorkerRunnable<Params, Result>() {
-
@Override
-
public Result call() {
-
-
mTaskInvoked.set(
true);
-
-
Result result = doInBackground(mParams);
-
-
postResult(result);
-
-
return result;
-
}
-
};
-
-
mFuture =
new FutureTask<Result>(mWorker) {
-
@Override
-
protected void done() {
-
super.done();
-
try {
-
postResultIfNotInvoked(get());
-
}
catch (ExecutionException | InterruptedException e) {
-
e.printStackTrace();
-
}
-
}
-
};
-
-
}
-
-
private void postResultIfNotInvoked(Result result) {
-
boolean wasTaskInvoked = mTaskInvoked.get();
-
if (!wasTaskInvoked) {
-
postResult(result);
-
}
-
}
-
-
private void postResult(Result result) {
-
Message message = mHandler.obtainMessage(MESSAGE_POST_RESULT,
-
new AsyncTaskResult<>(
this, result));
-
message.sendToTarget();
-
}
-
-
@SafeVarargs
-
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
-
return executeOnExecutor(sDefaultExecutor, params);
-
}
-
-
@SafeVarargs
-
private final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
-
Params... params) {
-
-
onPreExecute();
-
-
mWorker.mParams = params;
-
-
exec.execute(mFuture);
-
-
return
this;
-
}
-
-
private
static
class InternalHandler extends Handler {
-
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;
-
}
-
}
-
}
-
-
private
abstract
static
class WorkerRunnable<Params, Result> implements Callable<Result> {
-
Params[] mParams;
-
}
-
-
private
static
class AsyncTaskResult<Data> {
-
final AsyncTask mTask;
-
final Data[] mData;
-
-
@SafeVarargs
-
AsyncTaskResult(AsyncTask task, Data... data) {
-
mTask = task;
-
mData = data;
-
}
-
}
-
-
private void finish(Result result) {
-
onPostExecute(result);
-
}
-
-
final void publishProgress(Progress... values) {
-
mHandler.obtainMessage(MESSAGE_POST_PROGRESS,
new AsyncTaskResult<>(
this, values))
-
.sendToTarget();
-
}
-
-
/**
-
* 运行在主线程中,doInBackground()之前就会被调用,可以做一些准备操作
-
*/
-
protected void onPreExecute() {
-
}
-
-
/**
-
* 运行在线程池中,执行异步任务的地方
-
*/
-
protected abstract Result doInBackground(Params... params);
-
-
/**
-
* 运行在主线程之中,可以在doInBackground()中调用publishProgress()函数来触发该方法
-
*/
-
protected void onProgressUpdate(Progress... values) {
-
}
-
-
/**
-
* 运行在主线程之中,doInBackground()返回的Result结果会被推送这里
-
*/
-
protected void onPostExecute(Result result) {
-
-
}
-
-
/**
-
* -------------------------线程池的创建------------------------------------------
-
*/
-
private
static
final Executor sDefaultExecutor =
new SerialExecutor();
-
private
static
final Executor THREAD_POOL_EXECUTOR;
-
-
private
static
final BlockingQueue<Runnable> sPoolWorkQueue =
new LinkedBlockingQueue<>(
128);
-
-
private
static
final ThreadFactory sThreadFactory =
new ThreadFactory() {
-
private
final AtomicInteger mCount =
new AtomicInteger(
1);
-
-
public Thread newThread(Runnable r) {
-
return
new Thread(r,
"线程-Yobo-" + mCount.getAndIncrement());
-
}
-
};
-
/**
-
* CPU核心数量
-
*/
-
private
static
final
int CPU_COUNT = Runtime.getRuntime().availableProcessors();
-
-
static {
-
ThreadPoolExecutor threadPoolExecutor =
new ThreadPoolExecutor(CPU_COUNT -
1,
-
CPU_COUNT *
2 +
1,
30, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
-
threadPoolExecutor.allowCoreThreadTimeOut(
true);
-
THREAD_POOL_EXECUTOR = threadPoolExecutor;
-
}
-
-
private
static
class SerialExecutor implements Executor {
-
final ArrayDeque<Runnable> 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();
-
}
-
}
-
-
synchronized void scheduleNext() {
-
if ((mActive = mTasks.poll()) !=
null) {
-
THREAD_POOL_EXECUTOR.execute(mActive);
-
}
-
}
-
}
-
-
}
Test_My_AsyncTask
-
package com.yobo.yo_android.test_AsyncTask;
-
-
import java.util.Date;
-
-
import android.util.Log;
-
-
-
public
class Test_My_AsyncTask extends AsyncTask<Integer, Integer, String> {
-
-
@Override
-
protected void onPreExecute() {
-
super.onPreExecute();
-
log(
"onPreExecute.准备");
-
}
-
-
@Override
-
protected String doInBackground(Integer... integers) {
-
-
int add =
0;
-
for (Integer i : integers) {
-
publishProgress(i);
-
try {
-
Thread.sleep(
3000);
-
}
catch (InterruptedException e) {
-
e.printStackTrace();
-
}
-
-
add = add + i;
-
log(
"doInBackground.add=" + add);
-
}
-
-
String result =
"参数之和=" + add;
-
-
return result;
-
}
-
-
@Override
-
protected void onProgressUpdate(Integer... values) {
-
super.onProgressUpdate(values);
-
for (Integer i : values) {
-
log(
"onProgressUpdate.进度:" + i);
-
}
-
}
-
-
@Override
-
protected void onPostExecute(String s) {
-
super.onPostExecute(s);
-
log(
"onPostExecute.结果:" + s);
-
}
-
-
-
private void log(String msg) {
-
Log.e(
"Test_AsyncTask",String.format(
"%tr",
new Date()) +
": "
-
+ Thread.currentThread().getName() +
": " + msg);
-
}
-
}
转载:https://blog.csdn.net/qq_34589749/article/details/105663943