【问题标题】:how to pause AsyncTask for asking details from user?如何暂停 AsyncTask 以询问用户的详细信息?
【发布时间】:2013-09-09 02:34:45
【问题描述】:

我想在doInBackground() 的AsyncTask 中做一些工作时向用户询问一些细节(向用户显示一些带有 UI 线程中选择的对话框),并在用户选择后继续 doInBackground() 中的工作并选择对话框中的参数。

将此参数传输到doInBackground() 的最佳机制是什么?我应该如何暂停(并继续)执行doInBackground()(可能是object.wait() 和notify()?)的线程?我应该为此使用Handler 吗?

【问题讨论】:

  • 你为什么不去另一个 AsyncTask 呢?喜欢在接受用户输入之后?
  • AsyncTask 实际上会进行数据库版本升级...并且用户需要为新列指定一些数据。拆分数据库升级到多个AsyncTask...看起来结果不会很漂亮。
  • 看来我终于变成了这样的解决方案:我将在 onPreExecute() 中询问用户的所有信息...
  • 不要那样做...只需确保在执行之前已提供所有信息。 (例如onPreExecute)
  • @SALMAN 我明天会解决它,因为现在我想睡觉 :) 并将标记/发布接受的解决方案

标签: android android-asynctask


【解决方案1】:

在实际启动后台任务之前,我会要求用户输入。如果这是不可能的,有几种可能性:

  1. 您可以使用锁定对象并对其执行通常的 wait()/notify() 操作。不过,您仍然需要将数据从 UI 线程传递到后台线程

  2. 我会使用队列将数据从 UI 线程传递到后台线程,并让它处理所有锁定。

类似这样的东西(一种伪代码)

class BackgroundTask extends AsyncTask<BlockingQueue<String>, ...> {
    void doInBackground(BlockingQueue<String> queue) {
      ...
      String userInput = queue.take(); // will block if queue is empty
      ...
    }
}

// Somewhere on UI thread:
   BlockingQueue<String> queue = new ArrayBlockingQueue<String>(1);
   BackgroundTask task = new BackgroundTask<BlockingQueue<String>,....>();
   task.execute(queue);
   ....
   ....
   String userInput = edit.getText().toString(); // reading user input
   queue.put(userInput); // sending it to background thread. If thread is blocked it will continue execution

【讨论】:

    【解决方案2】:

    您可以使用Callable,将其提交给Executor,Executor 将返回FutureTask,然后您将在while 循环中等待直到FutureTask.isDone == true;

    这是一个例子http://programmingexamples.wikidot.com/futuretask

    【讨论】:

    • 这有点让事情变得比它需要的更困难,IMO。
    • @Alex Lockwood 我不同意你的观点。只回答提请注意 Executor 框架
    • 我只是在谈论这个有点微不足道的例子......不过,它绝对值得为长期/未来的运营提出。事实上,AsyncTaskdocumentation 也推荐它:)
    • @Alex Lockwood 当然,关于这个问题,从 doInBackground 获取用户输入的想法是非常错误的,正如您在对该问题的评论中已经指出的那样。
    【解决方案3】:

    希望我的回答一定能解决你的问题。

    //在 AsyncTask 的 doInBackground() 方法中执行所有以下代码

    String userInput="";
    
            YouActivity.this.runOnUiThread(new Runnable() {
    
                public void run() {
    
    
                //SHOW YOUR DIALOG HERE
    
                }
            });
    
    
            while("".equals(userInput))
            {
                YouActivity.this.runOnUiThread(new Runnable() {
    
                    public void run() {
    
                    userInput=editText.getText().toString();//fetching user input from edit Text    
                    }
                });
    
            }
    

    谢谢:)

    【讨论】:

    • 在一个线程中连续循环使用 100% 的 CPU 不是一个好主意。这可以用一个简单的 wait()/notify() 对替换,它将停止等待线程而不浪费资源。
    • 非常感谢发布答案而不是投票给我。
    • 如果您有更好的解决方案,请将其作为答案发布,而不是发表评论。谢谢
    猜你喜欢
    • 1970-01-01
    • 2021-09-23
    • 1970-01-01
    • 2018-11-30
    • 1970-01-01
    • 1970-01-01
    • 2016-05-18
    • 2020-11-16
    • 1970-01-01
    相关资源
    最近更新 更多