繁体   English   中英

Android AsyncTask进度更新挂起

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM