安卓中,Asynctask使用起来很方便,但也不是很完美,在做项目的时候,用一个ListView加载图片出现了java.util.concurrent.RejectedException这么一个异常信息,查资料发现,这是因为Asynctask线程池已满,再往里面去放线程,就导致这个异常出现。查Asynctask的源码发现,里面线程池只有五条,并且线程池的字段是private私有的,没法做修改,于是,把Asynctask源码拷贝一份,在自己的项目中添加,把线程池改大,于是,问题就解决了。修改的源码,图片能够顺利的加载:
package com.book.lover.utils;
import java.util.ArrayDeque;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutionException;
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.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import android.os.Handler;
import android.os.Message;
/**
* 重写系统的AsyncTask类,扩大线程池数量
*
* @author junjiex
*
* @param <Params>
* @param <Progress>
* @param <Result>
*/
public abstract class AsyncTask<Params, Progress, Result>
{
private static final String LOG_TAG = "AsyncTask";
private static final int CORE_POOL_SIZE = 20;//把线程池最大线程数改到20个
private static final int MAXIMUM_POOL_SIZE = 128;
private static final int KEEP_ALIVE = 1;
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<Runnable> sPoolWorkQueue = new LinkedBlockingQueue<Runnable>(
10);
public static final Executor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(
CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS,
sPoolWorkQueue, sThreadFactory);
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
private static final int MESSAGE_POST_RESULT = 0x1;
private static final int MESSAGE_POST_PROGRESS = 0x2;
private static final InternalHandler sHandler = new InternalHandler();
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
private final WorkerRunnable<Params, Result> mWorker;
private final FutureTask<Result> mFuture;
private volatile Status mStatus = Status.PENDING;
private final AtomicBoolean mTaskInvoked = new AtomicBoolean();
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);
}
}
}
public enum Status
{
PENDING, RUNNING, FINISHED,
}
public static void init()
{
sHandler.getLooper();
}
public static void setDefaultExecutor(Executor exec)
{
sDefaultExecutor = exec;
}
public AsyncTask()
{
mWorker = new WorkerRunnable<Params, Result>()
{
public Result call() throws Exception
{
mTaskInvoked.set(true);
android.os.Process
.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
return postResult(doInBackground(mParams));
}
};
mFuture = new FutureTask<Result>(mWorker)
{
@Override
protected void done()
{
try
{
final Result result = get();
postResultIfNotInvoked(result);
} catch (InterruptedException e)
{
android.util.Log.w(LOG_TAG, e);
} catch (ExecutionException e)
{
throw new RuntimeException(
"An error occured while executing doInBackground()",
e.getCause());
} catch (CancellationException e)
{
postResultIfNotInvoked(null);
} catch (Throwable t)
{
throw new RuntimeException(
"An error occured while executing "
+ "doInBackground()", t);
}
}
};
}
private void postResultIfNotInvoked(Result result)
{
final boolean wasTaskInvoked = mTaskInvoked.get();
if (!wasTaskInvoked)
{
postResult(result);
}
}
private Result postResult(Result result)
{
@SuppressWarnings("unchecked")
Message message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(this, result));
message.sendToTarget();
return result;
}
public final Status getStatus()
{
return mStatus;
}
protected abstract Result doInBackground(Params... params);
protected void onPreExecute()
{
}
@SuppressWarnings(
{ "UnusedDeclaration" })
protected void onPostExecute(Result result)
{
}
protected void onProgressUpdate(Progress... values)
{
}
protected void onCancelled(Result result)
{
onCancelled();
}
protected void onCancelled()
{
}
public final boolean isCancelled()
{
return mFuture.isCancelled();
}
public final boolean cancel(boolean mayInterruptIfRunning)
{
return mFuture.cancel(mayInterruptIfRunning);
}
public final Result get() throws InterruptedException, ExecutionException
{
return mFuture.get();
}
public final Result get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException
{
return mFuture.get(timeout, unit);
}
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;
}
public static void execute(Runnable runnable)
{
sDefaultExecutor.execute(runnable);
}
protected final void publishProgress(Progress... values)
{
if (!isCancelled())
{
sHandler.obtainMessage(MESSAGE_POST_PROGRESS,
new AsyncTaskResult<Progress>(this, values)).sendToTarget();
}
}
private void finish(Result result)
{
if (isCancelled())
{
onCancelled(result);
} else
{
onPostExecute(result);
}
mStatus = Status.FINISHED;
}
private static class InternalHandler extends Handler
{
@Override
public void handleMessage(Message msg)
{
@SuppressWarnings("rawtypes")
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 static abstract class WorkerRunnable<Params, Result> implements
Callable<Result>
{
Params[] mParams;
}
@SuppressWarnings(
{ "RawUseOfParameterizedType" })
private static class AsyncTaskResult<Data>
{
final AsyncTask mTask;
final Data[] mData;
AsyncTaskResult(AsyncTask task, Data... data)
{
mTask = task;
mData = data;
}
}
}