如何暂停活动?

3
我希望在用户执行某些操作(例如长按)时立即暂停“事件线程”/活动,并在用户执行其他操作(简单点击)时取消暂停。问题是,在我执行长按后,事件线程进入等待队列。因此,当我进行简单点击时,它不会被拦截。我该如何实现这一点?请注意,我不想通过显示进度对话框等方式暂停活动,我想保留我的活动处于前台并被暂停。以下是我尝试过的方法:/
 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();}
        }

    });

1
所有的UI事件都发生在一个线程中,因此在该线程上调用wait将导致所有事件在队列中等待。因此,您的应用程序将进入死锁状态。我看不到任何解决方法。 - Ron
如果您的应用程序在5秒内没有响应,则操作系统将显示一个对话框,上面会显示抱歉消息,这只是一种不可靠的处理方式。它不够用户友好,会让用户感到沮丧。我认为没有必要这样做。 - ngesh
1
你可以创建一个透明的活动在上面并捕获点击!当活动被暂停时,后面的活动也会被暂停!当点击发生时,您将返回到先前的活动。如果这是一个答案,请告诉我发布它。还有一件事!要创建空活动,请检查此链接http://sherifandroid.blogspot.com/2011/08/creating-global-dialogs.html 我已经做到了。 - Sherif elKhatib
@ntc 我有一个需求需要这样做,它是由用户操作(点击/长按)触发/取消触发的,因此用户可以控制它。 - con_9
有什么问题吗?关于全屏自定义和透明视图(例如相对布局中的最后一个子元素),它将拦截每一个触摸事件,您怎么看?只需触发其可见和不可见即可,不需要运行一个繁重的活动。或者我有所遗漏吗? - Knickedi
显示剩余5条评论
3个回答

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时执行某些操作,在此时刻,我不希望线程进入步骤C并等待用户操作。 - con_9
啊,处理这种情况的常见方法是在处理过程中引入一个暂停标志。当设置了此标志时,执行处理的线程将循环并继续检查此标志以实现暂停状态。取消暂停将将此标志设置回其原始值,从而允许正常执行恢复。 - spatulamania
这并不会立即暂停线程,但允许线程达到一个“可暂停”状态,在该状态下它可以监听“取消暂停”的通知。 - spatulamania
@spatulamnia,问题是如何从等待自身的主线程中通知主线程恢复执行。我想要添加的延迟不是绝对的,我不能睡眠一段明确的时间然后唤醒,而是需要通过 UI 操作(例如长按 - 请参见上面的原始帖子)来唤醒。 - con_9
@con_9 使用标志通知工作线程继续工作有什么问题吗?我已更新我的答案以演示它的工作原理。 - spatulamania

0
一个愚蠢的解决方案可能是这样的,在嵌入式系统中这是可行的方法,不过这肯定会降低性能。
class App extends Activity
{
private static boolean flag = true;

private void stopthread(){
while(flag){

}

}


private void handleUserEvent(){

//do your stuff and 

flag = false;
}
}

0
主线程处理UI事件,因此如果您通过sleep()阻塞它,则它将停止处理事件。
因此,您不能阻塞UI线程并期望通过用户操作解除阻塞。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接