【问题标题】:How to pause the activity?如何暂停活动?
【发布时间】:2011-09-08 09:17:43
【问题描述】:

我想在用户执行某些操作(例如长按)后立即暂停“事件线程”/活动,并在用户执行某些其他操作(简单单击)时取消暂停。问题是,在我长按后,事件线程进入等待队列。所以当一个简单的点击时,不会被拦截。我如何实现这一目标?请注意,我不想通过显示一些进度对话框等来暂停活动,我想在前台保留我的活动并暂停。这是我尝试过的:/

 final Thread t = new Thread(new Runnable() {

            @Override
            public void run() {
                 synchronized(this){    
                     try {
                         this.notify();
                         } catch (Exception e) {
                    e.printStackTrace();
                }
                 }
            }
        });
      vg.setOnLongClickListener(new View.OnLongClickListener() {

        @Override
        public boolean onLongClick(View v) {
            try {
                 synchronized(this){    
                     this.wait();
                     }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return true;
        }
    });
      vg.setOnClickListener(new View.OnClickListener() {


        @Override
        public  void onClick(View v) {
             synchronized(this){    
                 t.start();}
        }

    });

【问题讨论】:

  • 所有 Ui 事件都发生在一个线程中,因此在该线程上调用 wait 将导致所有事件在队列中等待。因此,您的应用程序将进入死锁。我看不出有任何方法可以完成这项工作。
  • @userSeven7s :我想我不会称之为死锁,它只是让主线程等待,并且有人应该对该对象调用通知,有人可能是另一个非事件或后台线程也是如此,所以它不是死锁。在我的情况下,我将主线程发送为(某种)睡眠状态,它不能听“任何东西”..
  • 如果您的应用在 5 秒内没有响应,那么操作系统将显示一个带有抱歉消息的对话框,这只是说它的处理方式不可靠。而且它对用户不友好,它会让用户感到沮丧。我认为没有必要这样做。
  • 您可以在此上方创建一个不可见的活动并捕获点击! while pause 后面的活动被暂停!当点击发生时,您将返回上一个活动。如果这是一个答案,请告诉我发布它..还有一件事!要创建空活动,请检查 sherifandroid.blogspot.com/2011/08/creating-global-dialogs.html 我已经做到了
  • @ntc 我有这样做的要求,它由用户操作(单击/长按)触发/未触发,因此用户可以控制它。

标签: android


【解决方案1】:

正如其他人所说,由于各种原因,暂停活动的主 UI 线程并不是一个好主意。

听起来您真正想做的是禁用各种 UI 元素,而不是暂停活动。这可以通过在要禁用/启用的各种元素上调用 setEnabled(boolean) 来完成。

当用户单击“暂停”按钮时,您可以浏览所有 UI 元素并禁用它们(“取消暂停”按钮除外)。然后,当用户单击“取消暂停”按钮时,您将重新启用所有禁用的元素。

编辑: 如果我了解您要查找的内容,这是一种暂停和取消暂停工作线程的方法。工作线程将在后台执行 doA() 和 doB(),并且可以在它们之间暂停。您可以使用此方法添加更多功能,甚至取消。


boolean mIsPaused = false;

final Thread workerThread = new Thread(new Runnable() {
   @Override
   public void run() {
      doA();
      checkPause();
      doB();
      checkPause();
      ...
   }
   }
});

private void checkPause() {
   while(isPaused()) {
      // you could also use the notify/wait pattern but that is probably needless complexity for this use case.
      Thread.sleep(50);
   }
}

private synchronized boolean isPaused() {
  return mIsPaused;
}

private synchronized void setPaused(boolean isPaused) {
  mIsPaused = isPaused;
}


pauseButton.setOnLongClickListener(new View.OnLongClickListener() {
   @Override
   public boolean onLongClick(View v) {
      // disable any UI elements that need it
      setIsPaused(true);
   }
});

unPauseButton.setOnLongClickListener(new View.OnLongClickListener() {
   @Override
   public boolean onLongClick(View v) {
      // re-enable any UI elements that need it
      setIsPaused(false);
   }
});

【讨论】:

  • @spatulamnia 感谢您的回复,但如果我只是想禁用某些元素,我不会让这个问题值得赏金。那将非常简单。我也不想暂停 UI 线程,但我确实希望获得与 UI 主线程已暂停一样的最终结果。例如:UI 线程正在处理以下步骤:A、B、C 现在用户执行一些操作在线程处于步骤 B 时的 UI 中,此时我不希望线程转到步骤 C 并等到用户操作。
  • 啊。处理这种情况的常用方法是在您的处理中引入 paused 标志。设置后,执行处理的线程将循环并继续检查此标志,从而影响暂停状态。取消暂停会将此标志设置回其原始值,从而恢复正常执行。
  • 这不会立即暂停线程,但允许线程达到“可暂停”状态,它可以监听“取消暂停”通知。
  • @spatulamnia 问题是如何通知主线程取消暂停,从等待自己的主线程。我想添加的延迟不是绝对的,我可以睡一段时间然后醒来起床,但唤醒呼叫来自 UI 操作(例如长按-参见上面的原始帖子)
  • @con_9 使用标志通知工作线程它应该继续工作有什么问题?我已经更新了我的答案来演示它是如何工作的。
【解决方案2】:

一个愚蠢的解决方案可能是这样,这是嵌入式系统的方式,尽管这肯定会降低性能。

class App extends Activity
{
private static boolean flag = true;

private void stopthread(){
while(flag){

}

}


private void handleUserEvent(){

//do your stuff and 

flag = false;
}
}

【讨论】:

    【解决方案3】:

    主线程处理 UI 事件,因此如果您阻止它(通过 sleep()),它将停止处理事件。

    因此您不能阻塞 UI 线程并期望通过用户操作解除阻塞。

    【讨论】:

      猜你喜欢
      • 2018-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多