基于AsyncTask的线程池封装
来源:互联网 发布:芬琳漆怎么样 知乎 编辑:程序博客网 时间:2024/06/05 16:02
/* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.common.library.utils;import java.util.ArrayDeque;import java.util.ArrayList;import java.util.LinkedList;import java.util.concurrent.BlockingQueue;import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.Executor;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;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.AtomicInteger;import android.os.AsyncTask;import android.os.Handler;import android.os.Message;/** * Modeled after {@link AsyncTask}; the basic usage is the same, with extra features: * - Bulk cancellation of multiple tasks. This is mainly used by UI to cancel pending tasks * in onDestroy() or similar places. * - Instead of {@link AsyncTask#onPostExecute}, it has {@link #onPostExecute(Object)}, as the * regular {@link AsyncTask#onPostExecute} is a bit hard to predict when it'll be called and * when it won't. * */public abstract class ThreadWork<Params, Progress, Result> {// messages of handler private static final int MESSAGE_POST_PROGRESS = 0x1; private static final InternalHandler sHandler = new InternalHandler(); private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); private static final int CORE_POOL_SIZE = CPU_COUNT + 1; private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1; private static final int KEEP_ALIVE = 1; private static final BlockingQueue<Runnable> sPoolWorkQueue = new LinkedBlockingQueue<Runnable>(128); 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()); } }; /** * An {@link Executor} that can be used to execute tasks in parallel. */ public static final Executor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory); private static class SerialExecutor implements Executor { final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>(); 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); } } } /** * An {@link Executor} that executes tasks one at a time in serial * order. This serialization is global to a particular process. */ public static final Executor SERIAL_EXECUTOR = new SerialExecutor(); private static final Executor PARALLEL_EXECUTOR = THREAD_POOL_EXECUTOR; /** * Tracks {@link ThreadWork}. * * Call {@link #cancellAllInterrupt()} to cancel all tasks registered. */ public static class Tracker { private final LinkedList<ThreadWork<?, ?, ?>> mTasks = new LinkedList<ThreadWork<?, ?, ?>>(); private void add(ThreadWork<?, ?, ?> task) { synchronized (mTasks) { mTasks.add(task); } } private void remove(ThreadWork<?, ?, ?> task) { synchronized (mTasks) { mTasks.remove(task); } } /** * Cancel all registered tasks. */ public void cancellAll() { synchronized (mTasks) { for (ThreadWork<?, ?, ?> task : mTasks) { task.cancel(true); } mTasks.clear(); } } /** * Cancel all instances of the same class as {@code current} other than * {@code current} itself. */ public void cancelOthers(ThreadWork<?, ?, ?> current) { final Class<?> clazz = current.getClass(); synchronized (mTasks) { final ArrayList<ThreadWork<?, ?, ?>> toRemove = new ArrayList<ThreadWork<?, ?, ?>>(); for (ThreadWork<?, ?, ?> task : mTasks) { if ((task != current) && task.getClass().equals(clazz)) { task.cancel(true); toRemove.add(task); } } for (ThreadWork<?, ?, ?> task : toRemove) { mTasks.remove(task); } } } public int getTaskCount() { return mTasks.size(); } public boolean containsTask(ThreadWork<?, ?, ?> task) { return mTasks.contains(task); } } private final Tracker mTracker; private static class InnerTask<Params2, Progress2, Result2> extends AsyncTask<Params2, Progress2, Result2> { private final ThreadWork<Params2, Progress2, Result2> mOwner; public InnerTask(ThreadWork<Params2, Progress2, Result2> owner) { mOwner = owner; } @Override protected Result2 doInBackground(Params2... params) { return mOwner.doInBackground(params); } @Override protected void onProgressUpdate(Progress2... values) { mOwner.onProgressUpdate(values); } @Override public void onCancelled(Result2 result) { mOwner.unregisterSelf(); mOwner.onCancelled(); } @Override public void onPostExecute(Result2 result) { mOwner.unregisterSelf(); if (mOwner.mCancelled) { mOwner.onCancelled(); } else { mOwner.onPostExecute(result); } } } private final InnerTask<Params, Progress, Result> mInnerTask; private volatile boolean mCancelled;/** * Construction with what create new instances can be canceled by Tracker. * * @param tracker * can retrieve instance like : <p> * ThreadWork.Tracke mTracke = new ThreadWork.Tracke(); */public ThreadWork(Tracker tracker) {mTracker = tracker;if (mTracker != null) {mTracker.add(this);}mInnerTask = new InnerTask<Params, Progress, Result>(this);} /** * Construction with what create new instances cannot be canceled later. */ public ThreadWork(){ mTracker = null; mInnerTask = new InnerTask<Params, Progress, Result>(this); } /* package */ final void unregisterSelf() { if (mTracker != null) { mTracker.remove(this); } } /** @see AsyncTask#doInBackground */ protected abstract Result doInBackground(Params... params); /** @see AsyncTask#cancel(boolean) */ public final void cancel(boolean mayInterruptIfRunning) { mCancelled = true; mInnerTask.cancel(mayInterruptIfRunning); } /** @see AsyncTask#onCancelled */ protected void onCancelled() {} /** @see AsyncTask#onProgressUpdate */ protected void onProgressUpdate(Progress... values){} /** @see AsyncTask#publishProgress */ protected final void publishProgress(Progress... values) { if (!mCancelled) { sHandler.obtainMessage(MESSAGE_POST_PROGRESS, new AsyncTaskResult<Progress>(this, values)).sendToTarget(); } } /** * Similar to {@link AsyncTask#onPostExecute}, but this will never be executed if * {@link #cancel(boolean)} has been called before its execution, even if * {@link #doInBackground(Object...)} has completed when cancelled. * * @see AsyncTask#onPostExecute */ protected void onPostExecute(Result result) {} /** * execute on {@link #PARALLEL_EXECUTOR} * * @see AsyncTask#execute */ public final ThreadWork<Params, Progress, Result> executeParallel(Params... params) { return executeInternal(PARALLEL_EXECUTOR, false, params); } /** * execute on {@link #SERIAL_EXECUTOR} * * @see AsyncTask#execute */ public final ThreadWork<Params, Progress, Result> executeSerial(Params... params) { return executeInternal(SERIAL_EXECUTOR, false, params); } /** * default execute on {@link #SERIAL_EXECUTOR} */ public final ThreadWork<Params, Progress, Result> executeDefault(Params... params) { return executeSerial(params); } /** * Cancel all previously created instances of the same class tracked by the same * {@link Tracker}, and then {@link #executeParallel}. */ public final ThreadWork<Params, Progress, Result> cancelPreviousAndExecuteParallel(Params... params) { return executeInternal(PARALLEL_EXECUTOR, true, params); } /** * Cancel all previously created instances of the same class tracked by the same * {@link Tracker}, and then {@link #executeSerial}. */ public final ThreadWork<Params, Progress, Result> cancelPreviousAndExecuteSerial(Params... params) { return executeInternal(SERIAL_EXECUTOR, true, params); } private final ThreadWork<Params, Progress, Result> executeInternal(Executor executor, boolean cancelPrevious, Params... params) { if (cancelPrevious) { if (mTracker == null) { throw new IllegalStateException(); } else { mTracker.cancelOthers(this); } } mInnerTask.executeOnExecutor(executor, params); return this; } /** * Runs a {@link Runnable} in a bg thread, using {@link #PARALLEL_EXECUTOR}. */ public static ThreadWork<Void, Void, Void> runAsyncParallel(Runnable runnable) { return runAsyncInternal(PARALLEL_EXECUTOR, runnable); } /** * Runs a {@link Runnable} in a bg thread, using {@link #SERIAL_EXECUTOR}. */ public static ThreadWork<Void, Void, Void> runAsyncSerial(Runnable runnable) { return runAsyncInternal(SERIAL_EXECUTOR, runnable); } private static ThreadWork<Void, Void, Void> runAsyncInternal(Executor executor,final Runnable runnable) { ThreadWork<Void, Void, Void> task = new ThreadWork<Void, Void, Void>() { @Override protected Void doInBackground(Void... params) { runnable.run(); return null; } }; return task.executeInternal(executor, false, (Void[]) null); } /** * Run {@code} on a worker thread, return execution result. * @param newTask * @return execution result */public static <T> T runCallable(Callable<T> newTask){ExecutorService pool = null;try {pool = Executors.newSingleThreadExecutor();Future<T> future = pool.submit(newTask);return future.get();} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}finally{pool.shutdown();}return null;} /** * Wait until {@link #doInBackground} finishes and returns the results of the computation. * * @see AsyncTask#get */ public final Result get() throws InterruptedException, ExecutionException { return mInnerTask.get(); } @SuppressWarnings("rawtypes") private static class AsyncTaskResult<Data> {final ThreadWork mTask; final Data[] mData; AsyncTaskResult(ThreadWork task, Data... data) { mTask = task; mData = data; } } private static class InternalHandler extends Handler { @SuppressWarnings({"unchecked", "rawtypes"}) @Override public void handleMessage(Message msg) {AsyncTaskResult result = (AsyncTaskResult) msg.obj; switch (msg.what) { case MESSAGE_POST_PROGRESS: result.mTask.onProgressUpdate(result.mData); break; } } }}使用方法:import android.app.Activity;import android.content.Context;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.Toast;import com.android.threadtest.utils.ThreadTask;public class MainActivity extends Activity implements OnClickListener {private Button mStartBtn;private Button mStopBtn;private Context mContext;private ThreadTask.Tracker mTracker = new ThreadTask.Tracker();private int index = 1;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mContext = this;mStartBtn = (Button) findViewById(R.id.button1);mStopBtn = (Button) findViewById(R.id.button2);mStartBtn.setOnClickListener(this);mStopBtn.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.button1:for (int i = 0; i < 10; i++) {// 当然还可以自定义类继承 ThreadTask,ThreadTask还有别的回调方法,如:onCanceled()等new ThreadTask<Void, Integer, String>(mTracker) {@Overrideprotected String doInBackground(Void... params) {try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}return "task finished for" + index++;}@Overrideprotected void onSuccess(String result) {Toast.makeText(mContext, result, Toast.LENGTH_SHORT).show();}}.executeSerial();}break;case R.id.button2:// 仅仅关闭当前mTracker追踪的tasks,而不是关闭线程池所有的tasks,因为线程池是全局的不能关闭mTracker.cancellAll();break;}}@Overrideprotected void onDestroy() {super.onDestroy();//仅仅关闭当前mTracker追踪的tasks,而不是关闭线程池所有的tasks,因为线程池是静态全局的,不能关闭,别的地方还有线程在线程池里运行!mTracker.cancellAll();}}
0 0
- 基于AsyncTask的线程池封装
- AsyncTask 的线程池
- 基于任务的线程封装
- Android异步线程AsyncTask封装
- AsyncTask的线程池使用
- AsyncTask Android的线程和线程池
- 基于对象风格的线程类封装
- 解决AsyncTask的线程池限制问题
- 对于线程池和AsyncTask的理解
- 基于AsyncTask的图片下载
- AsyncTask的套路(线程间通信中处理耗时任务的工具封装类)
- AsyncTask线程池使用
- AsyncTask中的线程池
- AsyncTask与线程池
- Android 的线程(AsyncTask、HandlerThread、IntentService详解)和线程池
- Android 的线程(AsyncTask、IntentService详解)和线程池
- Android 的线程(AsyncTask、HandlerThread、IntentService详解)和线程池
- Android AsyncTask 深度理解、简单封装、任务队列分析、自定义线程池
- 出错总有原因 之 关于重新编译
- java特点
- 出错总有原因 之 仅有第一次编译不成功
- oracle OCP认证学习日志(2)
- Ubuntu 13.10中安装eclipse后菜单栏下拉失效
- 基于AsyncTask的线程池封装
- 整理硬盘里的资料
- Linux chown命令详解
- Intent数据传递
- 左耳朵耗子给出的学习指南
- O(n)回文子串算法
- project、target的build settings、info信息剖析
- 2014开年文章
- poj-1947-Rebuilding Roads