Usage of timer may be slowing my application down - java

I'm writing an app that will have a list of "active alarms" for users to interact with in various ways. Each timer is represented by an object that contains a "created time" that represents when the alarm came into existence. I have a fragment that displays all of the alarms to a user, where each Alarm is represented as a RelativeLayout with a TextView containing the "age" of a timer, where age is calculated by the created time subtracted from the current time. The requirements for my application state that the age needs to be calculated and updated once every second.
Here's the code for my timer:
final Handler myHandler = new Handler();
final Runnable myRunnable = new Runnable(){
public void run()
{
alarmDuration.setText("Age: " + tempAlarm.getAge());
}
};
try {
//This timer is meant to update the time on each Alarm once a second.
Timer timer = new Timer();
TimerTask timerTask = new TimerTask() {
#Override
public void run() {
myHandler.post(myRunnable);
}
};
//Schedule the timer to go every second.
timer.schedule(timerTask, 0, 1000);
}
catch(Exception e)
{
e.printStackTrace();
}
Each alarm view has its own Handler, Runnable, and Timer. Here's where my problem lies: When I am displaying less than 10 of these timers, the app seems to run fine and can manage the updating with no problem. However, I tried loading somewhere in the realm of 100 alarms, and the application began to drop frames (as seen in my console). On configuration change (such as rotating the screen), I was getting dropped frames in the realm of 50-60.
Is this a good way to update these textViews or is there a method that would create less of a drag on the application? One idea I had was to possible put the IDs of all the alarm age views into an ArrayList and then have just one Handler, Runnable, and Timer to update the entire list.
Any other suggestions would be greatly appreciated!

Related

App Stops refreshing after a couple of hours?

I build a printer app that i need to run 24/7 to check if there is new order, I wrote a code that refreshes the activity every 60 seconds to check if there's a new order. The problem is that it runs fine for an hour or so but after that the activity stops refreshing automatically until i click the refresh button. Then again it works for an hour or so and again stops refreshing automatically. Can somebody please help me with this?
I've use the following code to refresh the activity.
private static final int delay = 60;
Timer timer;
OrderAdapter oadaptor;
timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
getLiveOrders(bID,"ALL");
oadaptor.notifyDataSetChanged();
}`enter code here`
});
}
}, 0, delay * 1000);
You shouldn't be doing that with a Timer but a service instead. That way it will continue running even if the app is in the background.

Vaadin refresh grid after adding row

My grid is not refreshing automatically after adding a row. I've tried several solutions from other questions but they didn't work. E.g. grid.clearSortOrder(); and grid.markAsDirty();. My goal is to add rows after time periods. Therefore I'm using a Timer and the rows are added but the grid does not refresh until I click in the table.
Easy code example:
Grid grid = new Grid();
grid.addColumn("Name");
grid.addColumn("Age");
Timer timer = new Timer();
timer.schedule(new TimerTask(){
public void run(){
grid.addRow("Exmaple","99");
}
}, 1000, 1000);
You will Need Server push for this. See Vaadin-Doc-Serverpush.
You want to change the UI from another Thread (Timer.schedule() will execute in another thread).
Vaadin callbacks are triggered by user interactions like mouse press on a button, selection of an option and so on. When you need the user interface to reflect a change that was not caused by the mouse/keyboard, you need to enable server push:
#Push
public class App extends UI {
#Override
public void init(VaadinRequest request) {
timer.schedule(new TimerTask() {
public void run() {
access(() -> grid.addRow("Example", "99"));
}
}, 1000, 1000);
}
}
Note the usage of UI.access(Runnable) to lock the UI when it is accessed from a non-request thread.

How to change a java timer's interval

I'm working on an android Tetris game. And an IllegalStateException occurred when executing
timer.scheduleAtFixedRate (task, 0L, milliseconds);
in
public void setTimerInterval (int milliseconds) {
timer.cancel ();
timer = new Timer ();
timer.scheduleAtFixedRate (task, 0L, milliseconds);
}
Am I doing this wrongly or something?
I need to cancel the timer and create a new one because I cannot change the interval of the timer unless you schedule a new task for it, right?
I read a post here and here is a quote of one of the answers:
A timer can only be scheduled once. If IllegalStateException isn't happening when you call cancel(), but when you try to reschedule the timer, just reinstantiate the timer and then schedule it. Otherwise, I'm not sure.
I didn't use the accepted answer of the that question because it's about pausing and resuming the timer.
I reinstantiated the timer as shown above but there is still a IllegalStateException.
Handler handler = new Handler();
handler.post(new Runnable() {
#Override
public void run() {
// do the task here
handler.postDelayed(this, milliseconds); // set time here to refresh textView
}
});
Make the milliseconds global and change that, maybe that would be a better solution.
How to change a java timer's interval
Java Timers don't have intervals. Timer tasks have intervals.
Solution: cancel and reschedule the TimerTask, not the Timer.

Handling timers in java

I have an application which runs a timer to check for idle time and once there is no activity for 10 seconds the application will close. I have nearly 100 screens and i want to track the inactivity seconds on all the screens. Its hard for me to write the handling events in all buttons, textboxes, labelboses one by one. What i have to do is add 10 seconds on every action of the user on the application. Even if it is mousemove add 10 seconds so tat the application wont close for another 10 seconds. Is there any way to handle this effectively ?
I would suggest the following handler:
final Timer tm = new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("10 SECONDS AND NOTHING HAPPENED");
}
});
tm.start();
Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
#Override
public void eventDispatched(AWTEvent event) {
tm.restart();
}
}, -1);
You could look into Toolkit.addAWTEventListener this allows you to add a MouseMotionListener to react to mouse movements throughout your app and act accordingly.

How to create a dialogbox that will pop up after 5 minutes of idleness by the user? (java)

I have a dialog box that is:
JOptionPane.showMessageDialog(null,"Once medicine is given, measure temperature within 5 minutes." ,"Medication" ,JOptionPane.PLAIN_MESSAGE);
When the user presses 'ok', it goes straight to a Jframe that ask the user to input the temperature using a slider and then pressing a button that takes it to the next set of things.
Anyways, I want to create somekind of inivisble countdown after the user presses 'ok', so after 5 minutes of idleness on the Jframe menu, one warning dialog box should appear on top of the JFrame and says something like "NEED ATTENTION".
This reminds me of actionListener. but it will be invoked by non-physical element, 5 minutes, (not by any click of button).
So Maybe the code should be like:
JOptionPane.showMessageDialog(null,"Once medicine is given, measure temperature within 5 minutes." ,"Medication" ,JOptionPane.PLAIN_MESSAGE);
temperature_class temp = new temperature_class(); // going to a different class where the the Jframe is coded
if (time exceeds 5 minutes) { JOptionPane.showMessageDialog(null, "NEED attention", JOptionPane.WARNING_MESSAGE);}
else { (do nothing) }
Code works:
JOptionPane.showMessageDialog(null,"measure temp" ,"1" ,JOptionPane.PLAIN_MESSAGE);
int delay = 3000; //milliseconds
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
JOptionPane.showMessageDialog(null,"hurry." ,"Bolus Therapy Protocol" ,JOptionPane.PLAIN_MESSAGE); } };
new Timer(delay, taskPerformer).start();
temperature_class temp = new temperature_class();
However, I want it do it only once. So how do I invoke set.Repeats(false)?
You could use a TimerTask with a Timer:
class PopTask extends TimerTask {
public void run() {
JOptionPane.show...
}
}
then where you want to schedule your task:
new Timer().schedule(new PopTask(), 1000*60*5);
This kind of timers can also be canceled with cancel() method
Essentially, after the initial option pane is shown, start a Timer. (A javax.swing one)
You will also need a class-level variable indicating if the temp has been entered yet.
JOptionPane.showMessageDialog(...);
tempHasBeenEntered = false;
Timer tim = new Timer(5 * 60 * 1000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (!tempHasBeenEntered)
JOptionPane.showMessageDialog("Hey, enter the temp!!");
}
}
tim.setRepeats(false);
tim.start();
You will need to flip the flag once a user enters a temp into the form.
Read the section from the Swing tutorial on How to Use Timers. When the dialog is displayed you start the Timer. When the dialog is closed you stop the Timer.
A Swing Timer should be used, not a TimerTask so that if the Timer fires the code will be executed on the EDT.

Categories