Flutter timer doesn't work when changed from milliseconds to seconds - flutter

When I change the Duration from milliseconds to seconds the app doesn't load correctly. I get no error in the debug, no logs, nothing, but the app simply doesn't respond to user interaction anymore, it's totally delayed. With milliseconds everything is normal again.
Timer.periodic(Duration(seconds: thisMaxSeconds), (timer) {
code...
}

May I know the value passed in the second (thisMaxSeconds) parameter of the Duration? If it's too high then periodic code execution will be delayed.

The likely cause here is that the thisMaxSeconds variable is set to 0. This causes the loop to run as quickly as possible, blocking UI interaction and updates.
Paste the following into dartpad to play around.
import 'dart:async';
void main() {
Timer.periodic(Duration(seconds: 0), (timer) {
print('Tick: ${timer.tick}');
if(timer.tick == 5){
print('Done');
timer.cancel();
}
});
}

Related

does the Timer class effect that mush of app performance?

i have the following timer which repeat it's self every single second
Timer? myTimer ;
String myString = '';
void myChick(){
myTimer = Timer.periodic(const Duration(seconds: 1), (_) {
if(myString.isNotEmpty ){
myString = '';
// here i am doing very simple work like change some of variblse
}
});
}
Note: i am not close myTimer never and it keep repeat its self as long as user use my app
now my question does it effect too mush of my app performance ?
Use a profiler and find out determiniscaly for your use case how does tax your application, but it will depend more on your overall architecture than on the timer itself.
flutter run --profile
Watch any video online if you need to learn how does it work:

Flutter - How to stop a periodic timer from outside the timer?

I have a flutter app in which I am simply opening a webview and am receiving messages via the javascript channel from the website. Now based on messages received from the website I have to start a periodic timer and stop (cancel) the timer on another message as well. As far as I can research I am just being allowed to cancel from within the timer or from dispose if the timer was initialized in initstate.
Here is my code right now -
JavascriptChannel _lightVibrationJavascriptChannel(BuildContext context) {
return JavascriptChannel(
name: 'x',
onMessageReceived: (JavascriptMessage message) {
var pattern = json.decode(message.message);
if (pattern["eventName"] == "start") {
//Make Periodic Timer
} else if (pattern["eventName"] == "stop") {
//Stop Periodic Timer
}
});
}
If I am making a global timer and initializing it at the time of making the periodic timer it will obviously not allow me to cancel it from within the else condition. I am bit lost. Any help?

Accessing and cancelling a periodic timer in dart/flutter

I am using a periodic timer for fetching data from server. I need to conditionally stop the timer when a bool (userExpectingTimerBool) has been set to false and also explicitly stop it by user. After stop, neither the periodic timer _timer, nor the last scheduled callback timer _t (or t) should run.
I have a fully working code now. But I feel some of it is redundant and some aspects of periodic timer is still not clear to me after reading documentation. Code is included below.
I have four questions:
Do I need to stop both _timer and _t (or t) to stop all scheduled tasks?
Which timer should I use to display search count (t.tick/_t.tick/_timer.tick)?
The callback function is a transient (nameless) method. Is the timer passed as an argument to it (t) a persistent or transient object (i.e., its value will be preserved across runs)?
What parts of the below code are redundant/can be reduced?
periodic timer with conditional run:
Timer _timer;
Timer _t;
bool userExpectingTimerBool=false;
var timerSearchCount;
var tSearchCount;
_timer = Timer.periodic(
Duration(seconds: intervalGiven),
(Timer t) {
_t= t;
if (userExpectingTimerBool == false) t.cancel();
tSearchCount=t.tick;
_displayResult();
}
);
timerSearchCount=_timer?.tick;
user-controlled stop timer function:
void stoptimer(){
setuserExpectingTimerBool(false);
if (_t !=null){_t!.cancel();}
if (_timer !=null){_timer!.cancel();}
checktimerActive();
}
When Timer.periodic invokes its callback, it should invoke it with itself as the callback's Timer argument. Therefore _t is just an alias for _timer, and having both is pointless. (You can verify this for yourself by printing identityHashCode(timer) and comparing against identityHashCode(_timer).)
See #1. Does not matter.
See #1. There is a single Timer object created by Timer.periodic.
if (userExpectingTimerBool == false)
If userExpectingTimerBool is not nullable, then it would be clearer as if (!userExpectingTimerBool). (If you believe that == false is more readable, then why not if ((userExpectingTimerBool == false) == true) and if (((userExpectingTimerBool == false) == true) == true), etc.) userExpectingTimerBool seems unnecessary anyway; if stoptimer is called, the Timer will be cancelled and prevent additional callbacks. You therefore shouldn't need to perform an additional cancellation check within the callback.
if (_timer !=null){_timer!.cancel();}
As written, _timer is non-nullable, so the null check is unnecessary. If you intend for _timer to be nullable, then you can replace the explicit if check with just _timer?.cancel();.

Is there a way for Flutter's Timer.periodic to wait for a function return plus a fixed duration before moving to the next cycle?

I use Timer.periodic with a duration normally. This works perfectly for my current use case.
Duration fiveSecs = const Duration(seconds: 5);
new Timer.periodic(fiveSecs, checkChange);
void checkChange(Timer timer) async {
//do some network calls
}
In this particular case I make network calls that take no longer than 500ms, and doing them every 5 seconds is enough for whatever depends on what those calls return.
Now I want to check for new values as frequently as 2 seconds, however, based on what needs to be checked a network call could take anywhere from a few hundred milliseconds to even 10 seconds. I could give a large margin and use a frequency of like 20 seconds for the timer, but in this case I would even prefer a 1 second frequency if possible.
So is there a way the timer could wait for a function, and still have a fixed duration like 1 second. So the maximum time it would take would be 1 second + callback runtime? Or is there a better way this could be achieved, I'm open to suggestions. Thank you.
void startTimer() {
_timer = Timer.periodic(Duration(seconds: 1), (Timer t) async {
print("lets wait for 5 seconds");
_timer.cancel();
await Future.delayed(Duration(seconds: 5));
print("Job is done");
print(DateTime.now());
print("Do it again");
startTimer();
});
}
I have encountered the same situation lately,
what I did was (in my case inside a static class) to add a static boolean value and toggle it accoding to my situation needs, later checking it's value inside the Timer.Periodic callback.
Timer.periodic(ConstantValues.socketTimerOperationDelay, (Timer t) async{
if(_udpHandlerCompleted){
_udpHandlerCompleted = false;
if(!_shouldSendBroadcast || _shutDown)
t.cancel();
else
_writeAllToUdpSocket(_udpSocket, data, ConstantValues.udpMulticastGroup, ConstantValues.udpMulticastPort);
_udpHandlerCompleted = true;
}
});
As you can see in my situation, I had to wait for the callback to end before I move to the next one, I believe this is what you're looking for, but in case you need to await for a different method the solution would be similar,
simply toggle the boolean _udpHandlerCompleted (in my case) in the other function.
Edit:
If my soultion helped you, kindly mark it as the accepted answer. Good luck!
At the end checkChange add Future.delayed(const Duration(seconds: 5), checkChange) then call it once instead of running the timer. You can add/check a boolean flag if you need to kill it at any point.

How to detect the scroll panel is still scrolling or not in GWT?

I need checkpoint to detect the scrollpanel is still scrolling or not. I am sending the server request while scrolling the scroll bar with the delay of 100 milliseconds.
I meant, every 100 milliseconds i am sending the request to server while scrolling. This is fine when i do scroll slowly in the grid. But, when I drag from page top to bottom
I could see there are multiple request is going to server. I want to know is there any flag to delete the long scroll. Please find the code
#Override
public void onScroll(final ScrollEvent scrollEvent)
{
int delay = 100;
super.onScroll(scrollEvent, delay);
}
I am using GWT class com.google.gwt.dom.client.BrowserEvents.ScrollEvent. I need below kind of logic
#Override
public void onScroll(final ScrollEvent scrollEvent)
{
int delay = 100;
if(stillScollbarScrolling) {
return;
} else {
super.onScroll(scrollEvent, delay);
}
}
So, I need to consider last request only as valid request. All the previous requests are invalid. I have logic to cancel all the previous logic. But, I need check point to still scroll bar is scrolling without release the bar.
Please help me..
If I understand you well, you need to cancel repeating scroll events. If so, you can use a Timer to do that.
Once a scroll event occurs you start a timer. If next scroll event is fired you check if a timer is still running. If so, it means that you have a repeating event that should be cancelled. If a timer is not running than it is not a repeating event and a request should be done.
Here is the code:
Timer timer = new Timer() {
#Override
public void run() {
// do nothing...
}
};
#Override
public void onScroll(final ScrollEvent scrollEvent) {
if(timer.isRunning()) {
// timer is running - stop the timer and do nothing (cancel event)
timer.cancel();
}
else
// timer is not running - do request
super.onScroll(scrollEvent);
// restart the timer with 100ms delay
timer.schedule(100);
}
Please, notice that the first scroll event will cause doing the request because the timer is not started yet.