Reputation: 585
This is my function who run a code every 2.5 seconds and check if a value seted to the true my progress will gone and ...
mHandler = new Handler();
continue_or_stop = true;
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
while (continue_or_stop) {
try {
Thread.sleep(2500); // every 2.5 seconds
mHandler.post(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
if (sp.getFromPreferences("state_update").equals("true")) {
progress_main.setVisibility(View.GONE);
layout_main.setVisibility(View.VISIBLE);
btn_save_send.setVisibility(View.GONE);
getOutputs();
MDToast.makeText(getActivity(), "وضعیت دستگاه با موفقیت بروزرسانی شد", Toast.LENGTH_LONG, MDToast.TYPE_SUCCESS).show();
sp.saveToPreferences("state_update", "false");
Intent intent = new Intent(getContext(), MainActivity.class);
startActivity(intent);
}
// you can set continue_or_stop to false, for stop
}
});
} catch (Exception e) {
// TODO: handle exception
}
}
}
}).start();
now i want a time out for this method if the value not seted to true after a (for example 12 seconds) progress should gone and Toast it to user that something goes wrong and try again
Upvotes: 2
Views: 1137
Reputation: 21144
Apparently this is more Android oriented, but I'll answer in general terms. And the other answer seems lacking the "12 seconds" timeout.
Well, you cannot really terminate a Thread
immediatly, or forcely. Consider a Thread
like a person, you need to kindly request him to terminate what he's doing. If he is able to do that, he will terminate, if not he will continue with its task.
As you're building the implementation of the task, you can check if someone asked you to terminate, with a special flag
Thread#isInterrupted()
Now, for this kind of thing using an ExecutorService
is the better option, as it returns a Future<T>
which can be canceled
. E.g.
final ExecutorService executorService = ExecutorService.newSingleThreadExecutor();
final Future<?> future = executorService.submit(runnable);
You can then say to the Future
"I want the result (which in your case is nothing), but with a timeout"
try {
future.get(12, TimeUnit.SECONDS);
} catch (final TimeoutException e) {
future.cancel(true);
}
The cancel(true)
method call will set the interrupted
flag of the Thread
.
Now, maintaining the code you already have, you might simply want to replace
while (continue_or_stop)
with
while (!Thread.currentThread().isInterrupted())
Adjust to your needs.
Upvotes: 1
Reputation: 29285
You can check for the timeout based on the number of trials. Also using thread and Thread.sleep
for running a periodic task is not a good practice.
To run a periodic task, you can post a Runnable
to a Handler
with some delay using postDelayed
method.
private Handler mHandler = new Handler();
private int mTrials = 0;
private Runnable mPeriodicTask = new Runnable() {
public void run() {
// Do the check
mTrials += 1;
if (mTrials == /* timeout number */) {
// timeout
} else {
mHandler.postDelayed(this, 2500);
}
}
}
To run the task:
mHandler.postDelayed(mPeriodicTask, 2500);
Upvotes: 1