When we deactivate a WP app, it can be tombstoned and terminated later by the OS. I need to save some unsaved app data to a persistent storage when the process is terminated, but not before this. Obviously, the Deactivated event cannot be used for this purpose as it is raised immediately when an app is moved to the background; the Close event is also not the event we need as it si not raised when the app process is terminated by the OS. Is there a special Windows Phone app event for that, something like Application_Terminated?
The problem is that the operating system only tombstones your app when it is under severe resource pressure. At the time it is not practical to wake up the app and run app code because it might risk whatever is currently in the foreground. This limitation exists on all modern mobile operating systems (Android, IOS included). This is just the cost of operating in a battery/resource friendly environment.
Having said that, it sounds like your backing store does not disambiguate between data the user "saved" and data that is just being cached until the user can finish the transaction. It would be useful to build the idea in. Think of it the way some of the smarter web sites on the internet now work. You can navigate away while you were in the middle of entering data and when you come back the site presents you with the partially filled form. The site understands that you weren't "done" but it respects the fact that you had provided some of the information you'd need to get "done".
What I'm saying here is that the problem is easily fixed by understanding and accommodating the way your users are likely to use the app. Thinking of your app like a web site (at least in this context) helps out things into perspective. Sorry about the longish answer. I hope it helps :)
There is no such event. You should save your state on Deactivated so that if the application is removed from memory (tombstoned) you can set yourself up again upon reactivation. If your problem is figuring out whether or not you need to restore state on Activated, check out the ActivatedEventArgs.IsApplicationInstancePreserved flag (http://msdn.microsoft.com/en-us/library/windowsphone/develop/microsoft.phone.shell.activatedeventargs.isapplicationinstancepreserved(v=vs.105).aspx). This flag tells you whether your app was tombstoned. If it wasn't, you can throw away the old state or overwrite it the next time you are deactivated.
Related
Coming from Android/WP7 and having been involved in Symbian projects by the past, i would like now to exactly understand the Symbian App life cycle. I want to understand how the Apps are killed.. if they are..
I found this:
"The Symbian platform is a modern preemptive multitasking operating system. Applications are created in their own process, running in a single main thread. The kernel preemptively schedules all threads in the system, based on their priority. While it is possible to create secondary threads, Symbian strongly encourages applications to co-operatively multi-task using active objects. ". Ref-link
"(..) applications may be up and running at the same time and the user may switch between active applications. When a asynchronous event occurred, running application is moved to the background but it remains active". Ref-link
It seems to me that the Apps are never killed, even when they are in background..
My question is: If the system does not kill them, how the system deals with the RAM issue? What about the possible battery drain? Does it mean that Symbian allows starting each single App, till there is not enough memory? Is there a specific meaning about the use of the Cancel/Back key that might destroy the App in certain conditions?
In UIQ framework i remember a lowMemory() call-back, but one never used that..
Thanks, for your help..
Symbian Apps are indeed never killed. That allows you to have several apps running in parallel without problems. Every app should of course provide the Exit command that closes the app. Back/Hide command just leaves the app runnning and takes user back to the menu. Also every well-written app should also manage his background tasks and allow to stop them when needed.
FYI, in Symbian there might be several background tasks running that are automatically started when phone is powered on. You can get the list of them when asking for a list of processes. You can also kill any process or app if your app has enough capabilities.
I am working on a Win8-UI-App (previously called Metro...) and trying to implement Periodic (Documentation for different methods) Tile Updates (Live Tiles) for the first time.
I found a couple of very good resources on the internet and was able to do it. Unfortunately the question of where I should register for the notifications remained unsolved:
Do I have to register for Notifications every time the app starts (e.g. in the App.xaml.cs OnLaunched() Method)? - Or is there an other, more professional way to do so? (I could imagine to save if I already registered for the service or is there a variable I can access to see whether notifications are registered?)
thank you!
PS: For everyone who is also new to this see this StackOverflow post, this example, the tile template types and the Dev Center for quick starting :)
Periodic updates will continue until they are explicitly stopped or your app is uninstalled. Technically, you only have to do that once. But, the Guidelines and checklist for periodic updates states
Call the StartPeriodicUpdate or StartPeriodicUpdateBatch method each
time your app is launched or brought into focus. This ensures that the
tile content will be updated each time the user launches or switches
to the app.
According to that, App launch and App resume are good candidates for a call to StartPeriodicUpdate.
My app uses iCloud (key-value store) to sync an unique id between multiple devices. This works accept at the point were it really has to work, at the first launch of the app. It looks like the device isn't yet familiar with the values from iCloud at first launch, only after the app is installed and has been running for a while.
I check for the iCloud value in the viewDidLoad function on main view of the app.
So, my questions:
Is this the expected behavior?
If yes, is there another solution?
Could it be the case this is only a problem when running from Xcode, not the shipping version? If so, how to test?
Thanks!
Jasper
I had a similar issue where the NSUbiquitousKeyValueStoreDidChangeExternallyNotification wasn't triggering on the first launch after install, no matter how long I waited. Setting an initial key in the NSUBiquitousKeyValueStore seemed to solve this.
Immediately after adding the observer to the default store, I call:
[[NSUbiquitousKeyValueStore defaultStore] setString:#"testValue" forKey:#"testKey"];
[[NSUbiquitousKeyValueStore defaultStore] synchronize];
I use different keys (i.e. not testKey) for the actual data I want to sync.
When you first run an iCloud enabled App it has to pull all the data from Apple servers. The time it takes to do so depends on many things like what kind of network you're currently on (Edge, 3G, GPRS, WLAN). It also depends on how much traffic the iCloud server currently has to handle so the request to the iCloud server may take a few more seconds, no matter what type of network connectivity you have.
To sum it up: Yes, it sounds absolutely normal.
If running your App depends on those settings consider implementing a "Wait" or "Loading" view that stays on the screen as long as it takes for the App to perform a initial synch and load all needed data from the cloud. To not block the UI forever also implement a timeout for this view (if iCloud data not loaded within X seconds, dismiss the view and notify user).
You have no guarantee NSUbiquitousKeyValueStore would have finished its first synchronization as your app is launched for the first time. (In fact, on iOS 5, it's often starting to sync as you launch your app for the first time).
There is no way to know if the first initial sync has already happened, is ongoing or has finished. You can (in fact should) subscribe to NSUbiquitousKeyValueStoreDidChangeExternallyNotification. The trick is that if your store is empty on the iCloud server, you won't get any notification after the initial sync (since your local store is empty and the cloud store is empty as well, nothing really changed "externally" after the initial sync…)
Normally, you should not rely on the initial sync being done.
Be optimist at launch, even if your store is empty, push your values (e.g. your unique id) right away. If the initial sync happens concurrently or after and there is already some value on the server, your local values will be reset to the server values and you will get the NSUbiquitousKeyValueStoreDidChangeExternallyNotification notification with the NSUbiquitousKeyValueStoreInitialSyncChange reason.
Finally, if you really think knowing about the initial sync being completed or not, please file a bug to bugreport.apple.com and explain why you really need that.
I have created a web-service app and i want to populate my view controllers according to the response i fetch(via GET) in main thread. But i want to create a scheduled timer which will go and control my server, if there becomes any difference(let's say if the count of an array has changed) i will create a local notification. As far as i read from here and some google results, i cant run my app in background more then ten minutes expect from some special situations(Audio, Vo-IP, GPS).. But i need to control the server at least one per minute.. Can anyone offer some idea-or link please?
EDIT
I will not sell the app in store, just for a local area network. Let's say, from the server i will send some text messages to the users and if a new message comes, the count of messages array will increment, in this situation i will create a notification. I need to keep this 'controlling' routing alive forever, whether in foreground or background. Does GCD give such a solution do anyone have any idea?
Just simply play a mute audio file in loop in the background, OR, ping the user's location in the background. Yes, that will drain the battery a bit, but it's a simple hack for in-home applications. Just remember to enable the background types in your Info.plist!
Note: "[...] I fetch (via GET) in main thread." This is not a good approach. You should never fetch any network resources on the main thread. Why? Because your GUI, which is maintained by the main thread, will become unresponsive whenever a fetch isn't instantaneous. Any lag spike on the network results in a less than desirable user experience.
Answer: Aside from the listed special situations, you can't run background apps. The way I see it:
Don't put the app in the background. (crappy solution)
Try putting another "entity" between the app and the "server". I don't know why you "need to control the server at least one per minute" but perhaps you can delegate this "control" to another process outside the device?
.
iOS app -> some form of proxy server -> server which requires
"babysitting" every minute.
I have a windows mobile application
I have noticed that it properly terminate on exiting, they simply minimize and take up memory. I need to cehck whether any instance of the same application is running in the taskmanager.If exists, i need to kill the process.
I need to write small app that would loop through all open application processes and terminate the required one.
Does such an application exist? If not, which onecould I use to write my own app for it?
Typically this is not how you solve this problem.
You should hold a 'mutex' in your application, and when it launches a second time, you first check this mutex, and if it's taken, you know your app is already running.
Find an appropriate global mutex to hold, and then check for it (I'm not sure what sort you can use on whatever version of Windows Mobile you are targetting, but a trivial search should help you find the answer).
If your app shows an [X] in the corner that's a Minimize button. Change the MinimizeButton property of the form and it will become an [ok] button which will close it.
The CF under Windows Mobile already enforces application singleton behavior. If the app is already running, the CF will look for it, find it, and bring it to the fore for you. No extra work needed.
If you really want to find the process and terminate it, that's done with the toolhelp API set. You can P/Invoke it or use the classes in the Smart Device Framework.