2012-12-06 2 views
1

Android 4.0.3을 대상으로하는 내 앱에서 버튼을 스위치로 사용했습니다. 버튼을 클릭하면 자원이 변경되고 (재생/일시 중지 간 전환) 일부 작업이 백그라운드에서 수행되고있었습니다. 버튼을 눌렀을 때 짧은 시간 동안 토글을 사용하지 못하게해야했습니다 (빠른 전환을 방지하기 위해). 내 활동에Android : Switch (ToggleButton) 및 스레드

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

기본적으로

지금까지 너무 좋아, 모든

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

OnClickListener를했다/:

는이를 위해이 같은 X 초를 기다리고 있었다 스레드를 생성 부드러운 매끄러운. 하지만 결국에는 그것을 스위치로 업데이트하길 원했습니다. 코드는 거의 동일합니다 (OnCheckedChangeListener로 바뀐 onClickListener 제외).

그러나 버튼을 한 번 클릭하면 리소스를 변경할 수 있습니다. 그래도 백그라운드 작업이 시작되지 않습니다 (이미 진동기 등으로 시도했지만 리소스 만 변경).

그래서 저는 Button이 사용하던 동작이 거의 없지만 리소스가 엉망이되었습니다. 어떤 생각이라도 환영 할 만하다. 감사.

+0

동기화 된 블록은 아무 것도하지 않습니다 ('this'는 로컬 변수이므로 공유되지 않는 스레드를 나타냄). 'button_ready'는 어떻게 선언되어 있습니까? '휘발성 '? – assylias

+0

button_ready는 클래스의 일반 변수이며 onCreate() 메서드 내에서 초기화됩니다. 다시이 메서드는 간단한 Button으로 완벽하게 작동하므로 스레드가 뭔가를 수행합니다 (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); 
    } 
} 

Fragment 또는 Activity 멀리 간다 장애인 기간 동안 떠나는 사용자에 의한 동시성 문제를 방지하는 것이 중요하다 당신의 전에 removeCallbacks를 호출 : 코드를 다음과 같이 보일 것이다. 이 경우 콜백을 사용 중지 한 후 사용자가 Fragment 또는 Activity으로 돌아오고 View이 저장된 상태로 복원되면 사용 중지 된 상태로 '고정'되지 않도록하는 것이 중요합니다.

+0

nevermind not comment : 다른 방법으로 변경하는 것을 잊었습니다! 완벽하게 작동합니다. 나는 아직도 그것이 나에게 오래된 솔루션으로 작동하지 않는 이유가 궁금하지만, 내가 원했던 모든 것은 그것이 작동하는 것입니다! 감사. – PeterGriffin

+0

상태 변경을 피하기 위해'if (button_ready)'에 의존했다면 문제는'ToggleButton'과'Switcher'가 내부적으로 체크 된 상태를 바꾸는 것이 었습니다 : 당신은'OnClickListener'에서 그것을 피할 수 없습니다. –

+0

글쎄, 스위치에 enable (false)를 부르는 것이 상태를 바꾸는 것을 막을 것이라고 나는 믿는다! 내 주변 코드가 없어도이를 시도했음을 의미합니다. 버튼을 비활성화하면 작동합니다. – PeterGriffin