03-11-2010 05:45 PM
Hey. I've never had a Timer fail to work, but then my first app was a system module with an alternate entry point. It started a Timer on autostartup ,and also when you used the alternate entry point, no problem.
My new app is a regular CLDC app (4.6). I should add it (like the Timer in my first app) uses a Singleton from the Runtime Store to put its Timer into, so that I don't have a situation where I have an earlier Timer running which I can't cancel. With the Singleton, I only have one Timer, so I can cancel it at will and reschedule.
When I start the Timer and use the End Call button on myhandset to effectively 'minimize' the app (still running), the Timer works. When I use the Escape arrow, it stops.
If someone could teach me a bit on this design aspect, appreciated.
03-11-2010 08:42 PM
Hi Peter. This was the case with the first app too, I guess mayb emy understanding of System Modules might be incomplete. My first more complex app started on cold boot (main) and set a Timer, then ended. The Timer worked fine. When I used the alternate entry point to open it, it set a Timer and exited. Also the Timer was ok. I had a Timer which continued running after my app finished (and a couple of Listeners too).
I don't really want the architecture of this app to be the same as the last unless I have to, I wonder I guess what feature made the difference.
03-12-2010 04:10 AM
Must admit I suspect my knowledge of Timers and Timertask is probably incomplete. Perhaps we will meet in the middle discussing this problem!
Anyway, when you have a system module and an Alternate entry, you probably start, in BlackBerry terms, two Applications. This point is not clear from any of the documentation I have seen.
However if on your auto-start you add Listeners to other applications (e.g. a listener for phone calls) this listener will continue to run even when your auto-start application has terminated.
However my understanding is that Timers run in the owning Application. In your other project's auto-startup, if you created a new Application, and then did not have this Application run through a System.exit(), it will still be running. In your other project did you create an Application and if so, did it go through a System.exit().
If not, then I'm going to have to try this myself to check my understanding.
03-12-2010 04:35 AM
an application ends after its processing has finished. it is not important if it was launched in an autostart entry point or not. many applications do not start an application in an autostart entry point but use it as a static context only. there is no application instance remaining after the processing finished.
if you have an app enter the event dispatcher or do processing without end (like while(true)...) it continues to run.
if you register listeners these listeners run, but the calling context does not continue.
some examples for autostart entry points:
registers an optionsprovider and exits. The timer is killed.
ITPolicyChangeListener itPolicyChangeListener = new ITPolicyChangeListener(); //extends Application
creates an application that continues to run - the static context however does not, the timer is killed.
Timer timer = new Timer();
timer continues to run, static context does not
03-12-2010 05:00 AM
A Timer works by starting a thread (hopefully on demand) and executing the scheduled tasks on that thread. Once there are no more scheduled tasks, the Timer may stop the thread. I'm 99% certain that's how a Timer is implemented on the BlackBerry.
When a Timer has to spawn a thread (e.g., once a task is scheduled when and there are no other scheduled tasks yet), the thread is spawned inside the process of the caller (the one scheduling a task) and thus the scheduled task will be executing inside the process of the caller. The interesting case is where a Timer's thread is already running inside a process (A), and another task is scheduled from another process (B) via the same Timer. In this case, I believe, the newly scheduled task will be executing inside the process in which the Timer thread was originally spawned (A), rather than inside the process that scheduled this task (B).
On the BlackBerry, once a process terminates, all threads owned by the process are terminated without any kind of warning or cleanup possibility (e.g., the finally clauses aren't invoked inside Thread.run). As a consequence, a Timer with a running thread may have its thread terminated without any warning or feedback, thus effectively stopping the execution of all scheduled tasks of that Timer. It would be interesting to see if the Timer will still start a new thread (in another process) once one more task is scheduled -- I suspect it would.
Thus, if you share a Timer between processes, the Timer's thread may be running in any one of these processes. Obviously, if it happens that one of the processes terminates, you may end up with a Timer that has scheduled tasks but which aren't being executed, unless you periodically schedule new tasks.
I suspect what's happening in your particular case is that you schedule a task on a Timer, it spawns a thread inside your application's process, then you terminate your app using the ESC key, thus terminating the process in which the application is running and thus terminating the Timer's thread too, thus effectively suspending the scheduled task. Next time you start your app, once you schedule a new task, the old task may resume (if it's still scheduled) and the new task will start running too -- until you terminate the app.
03-12-2010 05:31 AM
A facility for threads to schedule tasks for future execution in a background thread. Tasks may be scheduled for one-time execution, or for repeated execution at regular intervals.
Corresponding to each Timer object is a single background thread that is used to execute all of the timer's tasks, sequentially. Timer tasks should complete quickly. If a timer task takes excessive time to complete, it "hogs" the timer's task execution thread. This can, in turn, delay the execution of subsequent tasks, which may "bunch up" and execute in rapid succession when (and if) the offending task finally completes.
After the last live reference to a Timer object goes away and all outstanding tasks have completed execution, the timer's task execution thread terminates gracefully (and becomes subject to garbage collection). However, this can take arbitrarily long to occur. By default, the task execution thread does not run as a daemon thread, so it is capable of keeping an application from terminating. If a caller wants to terminate a timer's task execution thread rapidly, the caller should invoke the timer's cancel method.
If the timer's task execution thread terminates unexpectedly, for example, because its stop method is invoked, any further attempt to schedule a task on the timer will result in an IllegalStateException, as if the timer's cancel method had been invoked.
This class is thread-safe: multiple threads can share a single Timer object without the need for external synchronization.
This class does not offer real-time guarantees: it schedules tasks using the Object.wait(long) method.
03-12-2010 05:49 AM
Simon's point c) applies- I put my TImer in the runtime store. However, he said 'some examples for autostart entry points'. My app is not an autostart app.
After reading all the help, I guess I need to establish a timer in an independent process, a thread separate from my app...