I've a TextView where I want to set a message according to time ( hour of day). To achieve this I'm using-
Thread t2 = new Thread() {
#Override
public void run() {
try {
while (!isInterrupted()) {
Thread.sleep(3600000);
handler.post(new Runnable() {
#Override
public void run() {
int hour=Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
update(hour);
}
});
}
} catch (InterruptedException e) {
}
}
};
t2.start();
where update(hour) is used to update the message.
This works fine, however, the updating is done depending on the launching time. For example, the message should update at time 20:00. But if the app is launched at 19:59, the updating takes place at 20:59.
If I use Thread.sleep(1000) it works just as expected. But I feel like wasting resource by running the thread every second just to look for a 1 hour event. Is there any better way to do this?
Surely you need to check the current time, get the minutes past the hour, then work out from there when the next hour 00 will come. Then, just sleep time for those minutes, then for all the hours after that sleep for the full hour.
Take a look at AlarmManager.
The Alarm Manager is intended for cases where you want to have your application code run at a specific time, even if your application is not currently running.
Related
I am building an android application and I want an hour gap between two lines of code,
I use thread.sleep() method with 1800000 seconds but it makes my application irresponsive and closed the execution.
Any suggestions or help would be beneficial for me.
As #GaneshPokale suggested above, WorkManager is the best solution for your case.
Don't stop Main thread(=UI thread): Sleeping in the Main thread will stop your entire app, and it will lead you to ANR, which will make your app killed if your app is stopped more than 5 sec.
In this case, you need to create another thread. WorkManager is one of the solutions for such cases, which need to wait a long time. You can also use AlarmManager or some other ways.
Try running the code on a different thread:
class MyThread implements Runnable {
public void run() {
try {
Thread.sleep(1800000000);
} catch (InterruptedException err) {
//handle interruption
}
System.out.print("world!");
}
}
class Main {
public static void main(String[] args) {
System.out.print("Hello ");
Thread t = new Thread(new MyThread());
t.start();
}
}
This will allow the main thread to continue running tasks while the second one is waiting in the background.
I wonder what the best way is to implement this behavior:
I have an event X with an id that happens from time to time.
If the event with a certain id happened, I want to execute some code after 25 seconds, except if X with the same id happens again, in that case I want it to be postponed again with 25 seconds.
What is the best way to implement this?
Here is how you can use a simple handler to delay running something for 25 seconds. It's up to you to figure out how to filter on some ID.
Handler handler = new Handler();
public void myEvent() {
// Remove any callback that may be registered, this will reset it if called before
handler.removeCallbacks(runMe);
// Execute the runnable in 25 seconds
handler.postDelayed(runMe, 25000);
}
Runnable runMe = new Runnable() {
#Override
public void run() {
// This will run after the postDelayed expires in 25 seconds
Log.d("TAG", "Run me at some time");
}
};
I have a Runnable r that is triggered periodically once per minute by handler.postDelayed(60*1000). And I test my code on a real device.
However I notice, when the phone is charging (AC or USB) , it works well, but if the phone is disconnected, the Runnable r will only run once every 20min or even worse, several hours. Thanks for any help!
Below is the code:
private final Runnable listen_to_server = new Runnable(){
public void run(){
new Thread() {
public void run() {
try {
handler.sendMessage(handler.obtainMessage(PING_SERVER,"listen"));
synchronized (listen) {
listen.wait();
}
handler.postDelayed(listen_to_server, 50000);
}
catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
};
In the Handler:
handler=new Handler() {
#Override
public void handleMessage(final Message msg) {
switch (msg.what) {
case PING_SERVER:
String type = (String) msg.obj;
add_log("ping server"); // print to screen and Log.d
...
...
}
}
}
Referring to this link i think the problem might be, as they said:
Android is not a real-time operating system. All postDelayed()
guarantees is that it will be at least the number of milliseconds
specified. Beyond that will be dependent primarily on what the main
application thread is doing (if you are tying it up, it cannot process
the Runnable), and secondarily on what else is going on the device
(services run with background priority and therefore get less CPU time
than does the foreground).
How to fix this? in this post the solution was the following:
You'll probably have better luck using the AlarmManager for such a
long delay. Handler is best for ticks and timeouts while your app is
in the foreground.
so try implement an AlarmManager looking at the doc.
Hope i helped :)
I have been using countdowntimer and it has performed perfectly. Now I want to implement the opposite (Something like stop watch) in which the time updates the screen every second and it increments forever till I stop.
Is there a way (similar in simplicity) that does the job sort of like Countdowntimer? I know I can use Timer and Timertask but this creates new thread and I read that it is not that reliable (or recommended).
Thank you
Looks like a Chronometer object is what you need.
By setting a tick listener, you will get a tick every second (unfortunately that's the minimum precision available, but from the question it looks like it's enough for your needs).
If you add the following class to you project, you can use it just like the CountDownTimer class:
public abstract class Stopwatch extends Thread {
int tickFreq;
public Stopwatch(int tickFreq) {
this.tickFreq = tickFreq;
}
abstract void onTick();
#Override
public void run() {
onTick();
try {
Thread.sleep(tickFreq);
}
catch (InterruptedException e) {
e.printStackTrace();
}
super.run();
}
}
And to use it, you would write:
new Stopwatch(1000){
#Override
void onTick() {
// Do whatever you want to do in here
}
}.start();
The param that's passed to the constructor (1000) is how often it should call onTick(). In this case, it's every 1000 milliseconds, i.e. every 1 second.
I'm making one application where user needs to do some task while time is passing. How I was thinking of doing it is:
show task to user -> start counting seconds -> if task is not solved within certain seconds, application writes: "You failed".
I have only one solution in my head, since I didn't come across same till now -
show task to used and start thread with counting seconds and waiting, something like:
sleep(1000);
secondsCounter++;
if (secondsCounter => LIMIT){
write("You failed!");
}
Still, something tells me that this is not proper way of solving it. Is there other (better) way?
Use a handler for this:
// set this to true if user succeeds before time runs out.
boolean userSucceeded = false;
new Handler().postDelayed(new Runnable() {
public void run() {
if (!userSucceeded) {
// write("you failed")
}
}
}, 1000L); // 1 second