Android异步任务机制之AsycTask
2017-08-20 16:30
369 查看
AsycTask 原理分析
Android 系统中我们经常把一些耗时的操作放在线程中,例如thread AsycTask 线程池 来执行一些耗时的操作,如与服务器数据的交互都需要放在线程中处理。
1,介绍
AsyncTask是Handler与线程池的封装用来可以后台更新前台的界面的一个实现类。 通过使用线程池减少线程的不断创建和销毁性能的消耗。使用线程池可以轮番的执行。
2,方法介绍
public abstract class AsyncTask<Params, Progress, Result> {} 参数 第一个表示doInBackground方法的参数类型 第三个 doInBackground返回类型 第二个:是onProgressUpdate方法的参数类型 new AsyncTask<Void,Void,Void>(){ @Override protected Void doInBackground(Void... params) { return null; } }; @Override protected Object doInBackground(Object[] params) { //执行后台任务 然后处理结果 Log.e("asyncTask::", "doInBackground"); // 在这个方法中可以调用publishProgress来更新任务进度 // (publishProgress内部会调用onProgressUpdate方法) try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } return null; } @Override protected void onPreExecute() { super.onPreExecute(); Log.e("asyncTask::", "onPreExecute"); } @Override protected void onPostExecute(Object o) { //后台任务后 执行此方法 super.onPostExecute(o); Log.e("asyncTask::", "onPostExecute"); } @Override protected void onProgressUpdate(Object[] values) { //若是下载任务 可以更新进度 super.onProgressUpdate(values); Log.e("asyncTask::", "onProgressUpdate"); } @Override protected void onCancelled(Object o) { super.onCancelled(o); Log.e("asyncTask::", "onCancelled1"); } @Override protected void onCancelled() { super.onCancelled(); Log.e("asyncTask::", "onCancelled2"); //先执行 } };
以上方法中,除了doInBackground方法由AsyncTask内部线程池执行外,其余方法均在 主线程中执行。
3,使用限制- 必须在主线程创建AsyncTack对象,因为Handler必须在主线程中被初始化。
- 执行execute()可以在非主线程中调用
4,从源码看AsyncTask到底是如何运行的首先看它的构造函数都干了些什么事
public AsyncTask() { 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); //调用doInBackground()方法 Binder.flushPendingCommands(); } catch (Throwable tr) { mCancelled.set(true); throw tr; } finally { postResult(result); ///********* 执行结果传入POSTResult(); } return result; } }; WorkerRunnable是一个匿名内部类,继承Callable 实现Call()方法。。。。 Params使用的是第一参数 Result使用第三参数 private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> { Params[] mParams; } 最后会在线程中调用 mWorker.call() 执行doInBackground(); 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); } } }; }
FutureTask 实际上是继承了Runnable接口
构造方法中把mWorker当参数传进FutureTask中最后会在 run方法中发现调用了mWorker.call();方法 然后会执行doinbackground();
我们在来看run方法到底是什么时候被调用的,从execute()可以找到一些线索。
@MainThread public final AsyncTask<Params, Progress, Result> execute(Params... params) { return executeOnExecutor(sDefaultExecutor, params); //sDefaultExecutor默认的串行线程 我们可以自己创建不同类型的线程池例如并行线程 } //并行线程 public static final Executor THREAD_POOL_EXECUTOR; static { ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory); threadPoolExecutor.allowCoreThreadTimeOut(true); THREAD_POOL_EXECUTOR = threadPoolExecutor; } @MainThread 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)"); } } //从这些判断可以看出execute()只能被执行一次不然会出错 mStatus = Status.RUNNING; onPreExecute(); //在后台任务执行前被调用 mWorker.mParams = params; exec.execute(mFuture); //mFuture当做参数传入execute中 //exec 代表创建的线程池 return this; } ////可以看到传入一个Runnaable实现类就行了 public interface Executor { void execute(Runnable command); } public static final Executor SERIAL_EXECUTOR = new SerialExecutor(); private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR; private static class SerialExecutor implements Executor { final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>(); Runnable mActive; public synchronized void execute(final Runnable r) { //mFuture代表传入的Runnable实现类 mTasks.offer(new Runnable() { public void run() { try { r.run(); //调用它的run()方法 然后会在它的run()方法中 调用Call()方法 } finally { scheduleNext(); } scheduleNext(); } }
“`
然后我们再来看一个开头中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实现类
private static class InternalHandler extends Handler { public InternalHandler() { super(Looper.getMainLooper()); } 因为这里需要获取的主线的的Looper所以这就解释了为什么需要在主线程中创 建AsnycTask对象了 为了sHandler将执行环境从后台线程切换到主线程(即在主 线程中执行handleMessage方法),我们必须使用主线程的Looper, 因此必须在主线程中创建sHandler。这也就解释了为什么必须在主线程中加载AsyncTask类,是为了完成sHandler这个静态成员的初始化工作。 @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异步任务机制之AsycTask
- [Android] Android异步任务机制之AsycTask
- Android异步任务机制之AsycTask
- 车路协同开发-Android异步任务实现机制
- Android中的AsyncTask异步任务机制
- android学习之消息机制与异步任务
- Android中AsyncTask(异步任务)和Handler(线程消息机制)的详解
- Android中的消息机制与异步任务
- Android异步任务机制—AsyncTask
- Android另一种异步任务机制:AsyncTask
- Android异步任务机制之AsycTask
- Android 异步任务:AsyncTask机制 源码详细版解析------从入门到升天
- Android异步任务机制之AsycTask
- Android异步任务机制之Handler
- Android核心技术之(5)---消息机制与异步任务
- Android异步任务机制之AsyncTask
- Android中实现异步任务机制方式:AsyncTask
- Android中实现异步任务机制的方式:Handler、AsyncTask
- Android中的异步任务机制
- Android多线程及异步任务消息处理机制(一)--Handler的使用