I’ve a very strange problem,
i try to disable a toggle button for just a sec in order to make impossible for people in my application to spamclick it.
my toggleButton has this listener :
videoToggleListener = new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
switchVideoSource();
switchBetweenSources.setEnabled(false);
freezeToggle.schedule(new TimerTask(){
@Override
public void run() {
switchBetweenSources.setEnabled(false);
switchBetweenSources.setEnabled(true);
}
}, 1000);
}
};
my application doesn’t force close on setEnabled(false) but do force close on setEnabled(true).
any idea ?
my log cat :
02-10 13:45:30.500: E/AndroidRuntime(7285): FATAL EXCEPTION: Timer-0
02-10 13:45:30.500: E/AndroidRuntime(7285): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
02-10 13:45:30.500: E/AndroidRuntime(7285): at android.view.ViewRoot.checkThread(ViewRoot.java:2932)
02-10 13:45:30.500: E/AndroidRuntime(7285): at android.view.ViewRoot.invalidateChild(ViewRoot.java:642)
02-10 13:45:30.500: E/AndroidRuntime(7285): at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:668)
02-10 13:45:30.500: E/AndroidRuntime(7285): at android.view.ViewGroup.invalidateChild(ViewGroup.java:2511)
02-10 13:45:30.500: E/AndroidRuntime(7285): at android.view.View.invalidate(View.java:5255)
02-10 13:45:30.500: E/AndroidRuntime(7285): at android.widget.TextView.invalidateDrawable(TextView.java:3916)
02-10 13:45:30.500: E/AndroidRuntime(7285): at android.graphics.drawable.LayerDrawable.invalidateDrawable(LayerDrawable.java:298)
02-10 13:45:30.500: E/AndroidRuntime(7285): at android.graphics.drawable.Drawable.invalidateSelf(Drawable.java:300)
02-10 13:45:30.500: E/AndroidRuntime(7285): at android.graphics.drawable.DrawableContainer.selectDrawable(DrawableContainer.java:227)
02-10 13:45:30.500: E/AndroidRuntime(7285): at android.graphics.drawable.StateListDrawable.onStateChange(StateListDrawable.java:99)
02-10 13:45:30.500: E/AndroidRuntime(7285): at android.graphics.drawable.Drawable.setState(Drawable.java:400)
02-10 13:45:30.500: E/AndroidRuntime(7285): at android.graphics.drawable.LayerDrawable.onStateChange(LayerDrawable.java:409)
02-10 13:45:30.500: E/AndroidRuntime(7285): at android.graphics.drawable.Drawable.setState(Drawable.java:400)
02-10 13:45:30.500: E/AndroidRuntime(7285): at android.view.View.drawableStateChanged(View.java:7374)
02-10 13:45:30.500: E/AndroidRuntime(7285): at android.widget.TextView.drawableStateChanged(TextView.java:2312)
02-10 13:45:30.500: E/AndroidRuntime(7285): at android.widget.CompoundButton.drawableStateChanged(CompoundButton.java:265)
02-10 13:45:30.500: E/AndroidRuntime(7285): at android.widget.ToggleButton.drawableStateChanged(ToggleButton.java:143)
02-10 13:45:30.500: E/AndroidRuntime(7285): at android.view.View.refreshDrawableState(View.java:7388)
02-10 13:45:30.500: E/AndroidRuntime(7285): at android.view.View.setEnabled(View.java:3147)
02-10 13:45:30.500: E/AndroidRuntime(7285): at fr.partisocialiste.psa.activity.VideosGridActivity$1$1.run(VideosGridActivity.java:101)
02-10 13:45:30.500: E/AndroidRuntime(7285): at java.util.Timer$TimerImpl.run(Timer.java:284)
02-10 13:45:32.804: I/Process(7285): Sending signal. PID: 7285 SIG: 9
EDIT :
i’ve change my listener this way :
videoToggleListener = new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
switchVideoSource();
switchBetweenSources.setEnabled(false);
freezeToggle.schedule(new TimerTask(){
@Override
public void run() {
runOnUiThread(new Runnable(){
@Override
public void run() {
switchBetweenSources.setEnabled(true);
}
});
}
}, 2000);
}
};
Thanks everybody, you’re awsome =) !
Obviously the problem is that you try to alter a
Viewfrom a non-UI thread. If you say that you don’t get this exception on the first line inside theTimerTask, just in the second, this may be because yourToggleButtonis already disabled, and this does not alter theView.To change the state of the
Viewfrom otherThreadthant the UI Thread you should userunOnUiThread().