【发布时间】:2014-06-27 22:16:47
【问题描述】:
在this SO question 的浪潮中,以及来自another one 的许多提示,我正在尝试实现一个AsyncTask 变体,其中包含可以优先处理的任务。
在我的CustomAsyncTask 课程中,我有:
public abstract class CustomAsyncTask<Params, Progress, Result> {
private static int CORE_POOL_SIZE = 1;
private static int MAXIMUM_POOL_SIZE = 1;
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, "CustomAsyncTask #" + mCount.getAndIncrement());
}
};
private static final BlockingQueue<DownloadTask> pPoolWorkQueue =
new PriorityBlockingQueue<DownloadTask>(10, new DownloadTasksComparator());
@SuppressWarnings({ "unchecked", "rawtypes" })
public static Executor PRIORITY_THREAD_POOL_EXECUTOR
= new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
TimeUnit.SECONDS, (PriorityBlockingQueue) pPoolWorkQueue, sThreadFactory);
//...
}
比较器:
public class DownloadTasksComparator implements Comparator<DownloadTask> {
@Override
public int compare(DownloadTask arg0, DownloadTask arg1) {
int res;
if (arg0 == null && arg1 == null) {
res = 0;
} else if (arg0 == null) {
res = -1;
} else if (arg1 == null) {
res = 1;
}
res = arg0.getPriority() - arg1.getPriority();
return res;
}
}
在扩展CustomAsyncTask 的DownloadTask 类中,我有一个priority 整数字段和一个getPriority() 方法。
我将任务执行称为:
DownloadTask dt = new DownloadTask(..., PRIORITY_NORMAL, ...);
dt.executeOnExecutor(CustomAsyncTask.PRIORITY_THREAD_POOL_EXECUTOR);
这是可行的:如果池大小为 1,则下载将一一执行;如果池大小为 2,等等。
注意:priority 整数具有任意值:
public static final int PRIORITY_HIGH = 10;
public static final int PRIORITY_NORMAL = 1;
但如果我将任务称为:
DownloadTask dt = new DownloadTask(..., PRIORITY_HIGH, ...);
dt.executeOnExecutor(CustomAsyncTask.PRIORITY_THREAD_POOL_EXECUTOR);
我有一个java.lang.ClassCastException: my.pkg.name.CustomAsyncTask$3 cannot be cast to my.pkg.name.DownloadTask
然后
at my.pkg.name.DownloadTasksComparator.compare(DownloadTasksComparator.java:1)
at java.util.concurrent.PriorityBlockingQueue.siftUpUsingComparator(PriorityBlockingQueue.java:334)
at java.util.concurrent.PriorityBlockingQueue.offer(PriorityBlockingQueue.java:447)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1295)
at my.pkg.name.CustomAsyncTask.executeOnExecutor(CustomAsyncTask.java:494)
at my.pkg.name.GetDownloadTaskListener$1.finishDownload(GetDownloadTaskListener.java:180)
at my.pkg.name.DownloadTask.onPostExecute(DownloadTask.java:330)
at my.pkg.name.DownloadTask.onPostExecute(DownloadTask.java:1)
at my.pkg.name.CustomAsyncTask.finish(CustomAsyncTask.java:536)
at my.pkg.name.CustomAsyncTask.access$0(CustomAsyncTask.java:532)
at my.pkg.name.CustomAsyncTask$InternalHandler.handleMessage(CustomAsyncTask.java:549)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
全部来自AndroidRuntime
我真的不知道...
编辑:此时,我已经封装了一个小型 Eclipse 项目,该项目以与大型应用程序完全相同的方式实现事物并遇到相同的问题。它逐字借用CustomAsyncTaskComparator 和CustomAsyncTask。没有给出视觉反馈。应用程序的进度只是一些 LogCat 输出。但它给出了这个想法。当超过两个任务入队时,应用 FCs。
https://www.dropbox.com/s/lrg4kscgw3f1xwr/ConcurrentTest.tar.gz
【问题讨论】:
-
你在代码的什么地方得到了那个异常?
-
它表示 Comparator 类的第 1 行。一旦高优先级的下载想要开始,而队列中已经有低优先级的下载,就会发生。
标签: android multithreading android-asynctask priority-queue