解决android中Asynctask遇到的问题

安卓中,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;
        }
    }
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值