2012-12-06 105 views
1

在我的应用程序针对Android 4.0.3,我曾经有一个按钮作为一个开关工作。点击按钮正在进行资源更改(在播放/暂停之间切换),某些任务正在后台执行。特别的是,当按下按钮时,我希望切换在短时间内不可用(以防止快速切换)。Android:切换(ToggleButton)和线程

要做到这一点,我创建了正在等待X秒线程,就像这样:

void blockButton(){ 
    new Thread() { 
     public void run(){ 
      try { 
         synchronized(this){ 
          button_ready = false; 
          sleep(5000); 
          button_ready = true; 
         } 
       } 
       catch(InterruptedException ex){} 
      } 
     }.start(); 
    } 
} 

,基本上在我的活动/ onClickListener

if(button_ready){ 
    // Start background stuff 
    changeButtonResource(); 
    button.setEnabled(false); 
    blockButton(); 
    button.setEnabled(true); 
} 

到目前为止好,一切都奔跑顺利。但我最终希望将其更新为Switch。代码几乎相同(除了onClickListener变成了OnCheckedChangeListener)。

但现在当我点击按钮一次,再次点击它将允许更改其资源 - 但后台任务不会启动(我试过用振动器和其他人已经,它只改变资源)。

所以我几乎有我的按钮曾经有的行为,但资源被搞砸了。任何想法都会比欢迎!谢谢。

+0

你的同步块没有做任何事('this'指的是一个局部变量,因此不共享的线程)。 'button_ready'如何声明? 'volatile'? – assylias

+0

button_ready是类中的常规变量,并在onCreate()方法中初始化。该方法再次与一个简单的按钮完美配合,所以线程可以做一些事情(更改var,wait,更改var)。 – PeterGriffin

+0

为了让你的代码线程安全(可能或不可能解决问题):删除同步块并将你的变量声明为volatile:'private volatile boolean button_ready;'。 – assylias

回答

1

您不需要创建另一个线程。 View.postDelayed(Runnable)为您在超时后启用按钮(或执行其他UI操作)提供了更简单的方法。你的代码应该是这个样子:

class ... extends Fragment { 
    private final Runnable enabler = new Runnable() { public void run() { 
     button.setEnabled(true); 
    }}; 

    private View button; 

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View result = ... 
     button = result.findViewById(...); 
     button.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View v) { 
       button.setEnabled(false); 
       ... 
      } 
     }); 
     ... 
    } 

    public void onDestroyView() { 
     ... 
     button = null; 
    } 

    public void onPause() { 
     ... 
     button.removeCallbacks(enabler); 
    } 

    public void onResume() { 
     ... 
     button.setEnabled(true); 
    } 
} 

FragmentActivity消失重要的是要避免因用户在无效期间离开并发问题前调用removeCallbacks。在这种情况下禁用回拨后,确保当用户回到FragmentActivityView恢复其保存状态时,您不会在禁用状态中“卡住”。

+0

没关系编辑注释:我忘了改变其他方式!完美的作品。我仍然想知道为什么它不适用于我的旧解决方案,但嘿,我只想要它的工作!谢谢。 – PeterGriffin

+0

如果你依靠你的'if(button_ready)'来避免状态改变,问题在于'ToggleButton'和'Switcher'在内部改变了它们的检查状态:你无法避免从'OnClickListener'中避免这种情况。 –

+0

那么,我相信在Switch上调用enable(false)会阻止它切换状态!我的意思是我没有使用我周围的代码尝试它 - 只是用一个禁用它的按钮 - 它工作! – PeterGriffin