【问题标题】:How to wait for all button click functions to complete如何等待所有按钮点击功能完成
【发布时间】:2020-06-07 23:06:08
【问题描述】:

我的程序在按下按钮时运行一个函数。在里面,我执行一个动作,然后显示一个进度对话框微调器。现在我想等到我得到“响应”,所以我在 T 时间内获得了一个信号量。

在我尝试获取信号量之前,我认为该函数会执行并且会显示一个进度条,但程序最终会进入信号量获取并休眠,从而阻塞其他函数(可能)。信号量超时后显示进度对话框。在继续之前,如何确保所有先前的功能都成功完成?这是我的 onClick 函数:

public void onButtonClick(View view) throws InterruptedException {
   do_action();
   progress_dialog.show();

   boolean acquired = my_semaphore(15, TimeUnit.SECONDS);
   if (!acquired) {
       // action timed out
       // do something
   } else {
       // set elsewhere in the program
       // a - ok
   }
}

我怎样才能更好地实现它?

【问题讨论】:

    标签: java android


    【解决方案1】:

    我不确定我是否完全理解您的问题,但如果我理解正确,这就是我会做的。将您的do_action(); 调用移动到progress_dialog.show(); 之后,然后从do_action(); 方法中调用progress_dialog.dismiss();(在您想要的代码执行后结束)。另请注意,进度对话框已被弃用,您应该改用进度条之类的东西。如果我误解了你的问题,请告诉我,我会尽力给你答案。

    【讨论】:

    • 澄清...当我插入信号量获取调用时,do_action 和进度对话框没有完全执行。如果没有 get 调用,两个函数都会执行,我会看到进度对话框。当我添加信号量获取时,前两个功能即do_action和进度条显示没有完成,直到信号量超时我也看不到进度条。
    【解决方案2】:

    好吧,我知道一种方法可以完全满足您的要求,即异步任务。
    异步任务?

    AsyncTask 旨在使 UI 线程能够正确且轻松地使用。 然而,最常见的用例是集成到 UI 中,并且 这将导致上下文泄漏、错过回调或崩溃 配置更改。它也有不同的行为不一致 平台的版本,吞下来自 doInBackground 的异常,以及 与直接使用 Executor 相比,并没有提供太多实用性。

    在您的情况下,我认为 do_action() 正在执行后台任务。如果是这样,您可以像这样使用异步任务。

    public void onButtonClick(View view) throws InterruptedException {
         // Execute your task
         new ButtonClickTask().execute();
    }
    
     private class ButtonClickTask extends AsyncTask<Void, Void, Void> {
    
         // This task run on UI thread
         // Before starting the background task show the progress dialog.
         protected void onPreExecute () {
             progress_dialog.show();
         }
    
         // This task run on background thread, if you do any UI action from this function it will terminate your application and give an error.
         protected Long doInBackground(Void... params) {
             do_action();
             return null;
         }
    
         // Once your background task is completed. This method will be called.
         protected void onPostExecute(Void param) {
             // Your do_action() task is completed 
             // Now you could dismiss your progress_dialog here and do other tasks
             progress_dialog.dismiss();
         }
     }
    

    【讨论】:

    • 我之前尝试过这个方法,但是我得到了一个运行时异常,不记得错误,与 Looper 有关。无论如何,这种方法没有信号量获取,这是关键部分。当我执行 do_action() 时,我期望在程序的不同部分有一个响应,它将设置信号量。如果响应没有在超时时间内到达,我将执行清理。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-14
    • 2021-10-29
    • 2013-06-21
    • 2021-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多