在的this SO质疑并从another 之一,我试图实施的AsyncTask
变体可优先任务。
On the wave of this SO question and with many hints from another one, I'm trying to implement an AsyncTask
variant with tasks that can be prioritized.
在我的 CustomAsyncTask
I类有:
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;
}
}
在 DownloadTask
类扩展 CustomAsyncTask
我有一个优先级
整型字段和 getPriority()
方法。
In the DownloadTask
class extending CustomAsyncTask
I have a priority
Integer field and a getPriority()
method.
我打电话的任务执行为:
I'm calling the tasks execution as:
DownloadTask dt = new DownloadTask(..., PRIORITY_NORMAL, ...);
dt.executeOnExecutor(CustomAsyncTask.PRIORITY_THREAD_POOL_EXECUTOR);
本作品:如果池的大小为1,则下载Get逐一执行;如果池大小为2,等等。
This works: if the pool sizes are 1, the downloads get executed one by one; if pool size is 2, etc.
请注意:优先级整数有任意值:
note: priority Integers have arbitrary values:
public static final int PRIORITY_HIGH = 10;
public static final int PRIORITY_NORMAL = 1;
但是,如果我所说的任务:
But if I call the tasks as:
DownloadTask dt = new DownloadTask(..., PRIORITY_HIGH, ...);
dt.executeOnExecutor(CustomAsyncTask.PRIORITY_THREAD_POOL_EXECUTOR);
我有一个 java.lang.ClassCastException:my.pkg.name.CustomAsyncTask $ 3不能转换为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
我真的没有线索......
I really don't have a clue...
修改:在这一点上,我裹着一个小的Eclipse项目实现的东西正是大应用程序相同的方式和同样的问题受到影响。它借用 CustomAsyncTaskComparator
和 CustomAsyncTask
一字不差。没有视觉反馈给。该应用程序的进步只是一些LogCat中输出。但它给的想法。当两个以上的任务入队,应用程序功能界别。
EDIT: At this point, I've wrapped a small Eclipse project that implements things exactly the same way of the bigger application and suffers from the same issue. It borrows CustomAsyncTaskComparator
and CustomAsyncTask
verbatim. No visual feedback is given. The app's progress is just some LogCat output. But it gives the idea. When more than two tasks are enqueued, the app FCs.
https://www.dropbox.com/s/lrg4kscgw3f1xwr /ConcurrentTest.tar.gz
https://www.dropbox.com/s/lrg4kscgw3f1xwr/ConcurrentTest.tar.gz
推荐答案
正如你可能已经注意到了,同时期待通过的AsyncTask
实现,它在内部使用了 FutureTask提供
处理后台任务,而这正是被移交到执行程序
和潜在的排队它的工作队列。既然你已经得出自己的实现,你可以替换 FutureTask提供
与持有引用一个自定义的衍生的AsyncTask
,从你的比较
实施访问。
As you may have noticed while looking through the AsyncTask
implementation, it internally uses a FutureTask
to handle the background task, and that is what gets handed on to the Executor
and potentially queued on it's work queue. Since you are already deriving your own implementation, you could replace the FutureTask
with a custom derivative that holds a reference to the AsyncTask
, to be accessed from your Comparator
implementation.
此外,而不是替换的执行程序
自定义默认静态的AsyncTask
导数,你应该使用的在你的子类executeOnExecutor()
方法,以便它可以在一个通用的方式使用。
Also, instead of replacing the default static Executor
of your custom AsyncTask
derivative, you should instead use the executeOnExecutor()
method in your subclasses so that it can be used in a generic manner.
相关推荐
最新文章