У меня есть активность, которая управляет некоторым ASCII-контролем над сетевым портом на удаленном устройстве. Каждая кнопка нажимает на интерфейс, вызывая AsyncTask для обработки связи, и (наконец) отлично работает. Однако, если пользователь начинает мигать, как шимпанзе на трещине, система будет терпеть крах с слишком большим количеством вызовов в одном и том же сокете, поэтому я придумал небольшую функцию таймера, чтобы замедлить реакцию на их волнение.
Мне интересно, если кто-нибудь придумал лучший способ сделать это?
Во-первых, внутри onCreate:
btn_pwrtoggle = (Button)findViewById(R.id.pwr_btn);
btn_pwrtoggle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(!buttonMasher){
if(powerstat.equals("OFF")){
String[] commandToSend = {"POWER","ON"}
}else{
String[] commandToSend = {"POWER","OFF"};
}
deviceControl(commandToSend);
}
startButtonMashTimer();
}else{
Log.w("button masher","slow down there, monkey.");
}
}
});
Затем в действительной Деятельности:
Timer buttonTimer;
TimerTask buttonMonitorThread;
int chimpCrackCounter;
protected void startButtonMashTimer() {
chimpCrackCounter = 0;
buttonTimer = new Timer();
buttonMonitorThread = new TimerTask(){
@Override
public void run(){
buttonMasher = true;
if(chimpCrackCounter == 1){
buttonMasher = false;
buttonTimer.cancel();
}
chimpCrackCounter++;
}
};
buttonTimer.schedule(buttonMonitorThread, 0, 500);
}
Кажется, он работает очень хорошо (и может помочь кому-то с такими же трудностями), но я открыт для предложений.
Легкий способ не нажимать кнопку слишком часто - это сохранить время, когда нажата кнопка, а затем в следующий раз сравнить последний раз с текущим временем и если разница слишком мала, проигнорируйте действие.
final static long minTimeBetweenClicks = 1000;
long lastTime;
onClick(View v){
if( System.currentTimeMillis() < lastTime + minTimeBetweenClicks ) return;
//Handle the click
lastTime = System.currentTimeMillis();
}
Красота в том, что он не требует никаких новых потоков или таймеров, и ваши AsyncTasks не должны знать о кнопках.
Отключите Button
после щелчка (setEnabled(false
), возможно, в onPreExecute
, и включите после выполнения задачи в onPostExecute
.
Кроме того, не забудьте обратить внимание на изменения жизненного цикла. Ваш AsyncTask
может быть убит, если Activity
приостановлена, так что не забудьте проверить состояние в onResume
.
isEnabled()
)