首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在AsyncTask/Background中获取用户反馈(例如来自AlertDialog)?

问如何在AsyncTask/Background中获取用户反馈(例如来自AlertDialog)?
EN

Stack Overflow用户
提问于 2014-07-02 09:59:13
回答 1查看 175关注 0票数 0

Android 4+应用程序应该能够执行长时间运行的操作。例如,这可能是将100万个文件从A复制到B。若要不阻止UI,请使用AsyncTask在后台运行此操作。

假设操作在过程中间需要一些用户反馈才能继续其工作。“文件XY已经存在。重写、Irgnore还是重命名?”

所以我遇到了这样的解决方案:

  1. 在后台线程启动之前要求恢复功能,例如在开始复制/移动后台文件之前询问如何处理冲突。
  2. 不要处理冲突,但请注意,请询问用户在新操作中完成操作后如何处理冲突。
  3. 结束第一个冲突上的后台操作,请求用户反馈并继续一个新的后台操作。

我不喜欢这些解决办法。在第一种情况下,用户被要求提供反馈,即使根本没有冲突。如果必须按特定顺序处理步骤,则不可能有第二个解决方案。第三种解决方案将导致非常难以阅读/理解/维护的代码。

一个很好的解决办法是:

  • 停止后台线程
  • 命令用户界面线程并从用户那里获得反馈。
  • 恢复后台线程并使用反馈继续操作。

在Objectiv/iOS或C#中使用GCD,这不是什么大问题。但是如何在Android上使用AsyncTask来实现这一点呢?

EN

回答 1

Stack Overflow用户

发布于 2014-07-02 13:29:15

与此同时,我想,我找到了一个答案here:只需在doInBackground(...)中运行myActivity.runOnUiThread(...)并等待它。听起来不错,但不管用。AsyncTask/后台线程不等待Runnable完成:

代码语言:javascript
复制
private void copyFiles() {
    CopyTask copyTask = new CopyTask (this);
    copyTask.execute();
}

private class CopyTask extends CustomAsyncTask<Void, Void, Void> {
    private doCopy;

    @Override
    protected Boolean doInBackground(Void... params) {              
        // Custom code, e.g. copy files from A to B and check for conflict
        for (File file : allFiles) {
            doCopy = true;

            if (isConflict(file)) {
                // Stop current thread and ask for user feedback on UI Thread

                Runnable uiRunnable = new Runnable() {
                    public void run() {
                        // Pos 1. --> Execute custom code, e.g. use AlertDialog to ask user if file should be replaced...
                        doCopy = false;

                        synchronized (this) {
                           this.notify();
                        }
                    }
                });  

                synchronized(uiRunnable) {
                    // Execute code on UI thread
                    activity.runOnUiThread(uiRunnable);

                    // Wait until runnable finished
                    try {
                        uiRunnable.wait();
                    }
                    catch (InterruptedException e ) {
                        e.printStackTrace();
                    }
                }
            }

            // Pos 2. --> Continue work
            if (doCopy)
               copyFromAToB(File);
        }

        return null;
    }
}

我希望,当检测到冲突时,将执行Runnable并执行Pos 1 (用于解决冲突的Runnable内部代码),并执行BEVOR Pos 2。事实并非如此。Runnable被正确地执行,但是AsyncTask没有等待它完成。doInBackground的执行将不间断地继续进行。doInBackground和Runnable似乎是并行执行的(因为它们是在不同的线程上执行的),但为什么doInBackground不等待呢?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24528197

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档