[英]Android AsyncTask progress update hang
因此,我在编写自己的AsyncTask类(如系统,该系统在本地运行于ThreadPoolExecutor上)时遇到了麻烦。 在我决定实施事物的进度方面之前,一切工作都很好。 进度的工作原理类似于AsyncTask
,在UI线程上调用onProgressUpdate
函数。 我遇到的问题是,只要onProgressUpdate中有System.out或Log.x行,它就会无限期地挂起,没有错误或奇怪的警告。 代码如下:
public abstract class Task<A, B> {
private static final Executor EXECUTOR = getExecutor();
private static final int DEFAULT_PRIORITY = Thread.MIN_PRIORITY;
private static final int DEFAULT_PROGRESS_INCREMENT = 1;
private static final Executor getExecutor() {
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();
executor.setCorePoolSize(1);
executor.allowCoreThreadTimeOut(false);
// TODO set rejection handler
//executor.setRejectedExecutionHandler(new Handler());
// TODO set thread factory
executor.prestartCoreThread();
return executor;
}
public static class ExecutionListener<B> {
public void onPreExecute() {
Log.i("TASK", "Pre - Thread: " + Thread.currentThread().getId());
}
public void onPostExecute(B output) {
Log.i("TASK", "Post - Thread: " + Thread.currentThread().getId() + " - Output: " + output);
}
public void onProgressUpdate(int progress) {
Log.d("TASK", "Hello");
}
}
private Handler handler;
private ExecutionListener<B> executionListener;
private volatile int progress = 0;
private AtomicBoolean progressPublished = new AtomicBoolean(true);
private B output;
public Task() {
this.handler = new Handler();
this.executionListener = new ExecutionListener();
}
public void setExecutionListener(ExecutionListener executionListener) {
if(executionListener == null) {
this.executionListener = new ExecutionListener();
}
else {
this.executionListener = executionListener;
}
}
protected void updateProgress(int progressMade) {
Log.d("TASK", "Test");
progress += progressMade;
if(progressPublished.compareAndSet(true, false)) {
if(!handler.post(new Runnable() {
@Override
public void run() {
Log.d("TASK", new Integer(progress).toString() + " - a");
executionListener.onProgressUpdate(progress);
// Hangs below
progressPublished.lazySet(true);
Log.d("TASK", new Integer(progress).toString() + " - b");
}
})) {
Log.d("TASK", "Failed to post");
}
}
}
protected void updateProgress() {
updateProgress(DEFAULT_PROGRESS_INCREMENT);
}
protected abstract B doTask(A input);
public void execute(final A input, final int priority) {
EXECUTOR.execute(new Runnable() {
@Override
public void run() {
Thread.currentThread().setPriority(priority);
handler.post(new Runnable() {
@Override
public void run() {
executionListener.onPreExecute();
}
});
output = doTask(input);
if(!handler.post(new Runnable() {
@Override
public void run() {
Log.d("TASK", "Done");
executionListener.onPostExecute(output);
}
})) {
Log.d("TASK", "Failed to post post");
}
}
});
}
public void execute(final A input) {
execute(input, DEFAULT_PRIORITY);
}
}
ExecutionListener
只是一个类,用于重写要在UI上运行的方法,就像AsyncTask的方法一样。 该代码使用Runnable对象执行doTask方法,并将更新/结果发送到ExecutionListener中的相应方法。
Thread.currentThread()
部分只是为了确保事情在我想要的线程上运行。 该问题仅在运行经常调用updateProgress()
的Task时才显示出来-我曾尝试将线程睡眠置于onProgressUpdate()
方法中,这似乎可以解决问题,尽管显然这不是一个好的解决方案。
Log.x / System.out似乎也只有一个问题-我不知道它们中任何一个的调用频率是否会导致这种问题。 我对这个进度功能和日志一无所知,因此任何建议都将不胜感激-我也发现这很难解释,所以请问您是否需要我澄清一下!
事实证明Thread.currentThread()。getId()有问题。 删除该部分可以修复所有问题。 在这里跟进问题: Java Thread getId()线程安全吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.