2012-12-06 41 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