According to J. Likness on page 166 of "Building Windows 8 Apps with C# and XAML," in speaking of the OnResuming event: "The main reason [for this event ] is for applications that provide timely data to refresh their information."
I have one page in my app that has such data; so, if the user has resumed the app, and he explicitly
returns or is implicitly/automatically returned to that page (assuming he was on that page when the app was suspended), I want to refresh the data. But how do I know that my app was suspended/resumed?
My idea is to set a bool that the data-rich page can interrogate in its OnNavigatedTo() event; if it is true, I will refresh the data. Is there a better way to do this, and perhaps more importantly: is the OnNavigatedTo() event fired if the user was on that page, the app was suspended, and then resumed? Or does the app view the page as never having been left, and thus it is not being navigated back to? Perhaps another page-level event would be more appropriate?
I'd say you need to determine what the threshold is for when the page of interest needs to be refreshed; I don't think it's as simple as a Boolean. A user could suspend and pretty much immediately resume (say within 15 seconds) and that may not merit a refresh, but that same user could also linger on secondary page, never suspend, and come back to a page 30 minutes later, in which case the page data could be quite stale. Your Boolean may need to be more of a timestamp.
That said, the Resuming event does not fire OnNavigatedTo. If you need to know what page you're coming back to, you'd need to save that info when you suspend, perhaps in LocalSettings. But now consider that if you're using SuspensionManager in C#/XAML, that is already happening on your behalf, and if you think about it, the behavior you want is not too different (if at all) from what should occur when the application comes back from a terminated state.
So in a similar fashion, you could add a call
await SuspensionManager.RestoreAsync()
as your implementation of the Resuming event. That would, in turn, cause an OnNavigatedTo and you'd run through the normal logic of bringing up that page.
It's technically not resuming anymore, you're just using the resuming event to trigger the reload of the entire page. That could be overkill depending on the nature of the page (e.g., maybe there's a lot of semi-static data and only a tiny bit of volatile data - resuming doesn't need to restore the static data). You may want to dial back how much is refreshed on a 'resume' versus a 'terminate,' but since SuspensionManager is code you can see and change, so you can control that level of granularity. And maybe it's here that you introduce you're idea of the Boolean to differentiate what needs to be done in LoadStateAsync when it's invoked by Resuming versus by other means.
Related
I’m using the onPause() method in my app so that users become ‘offline’ in my chat when the app is on pause. I found it very useful.
But the thing is that each time a user navigates between activities, the method is called for like a millisecond. This way, users are ‘online’ in activity A, ‘online’ in B, but ‘offline’ in between.
Because I use a green dot to described online users, it is very annoying since it changes to grey and then green again each time.
Is there a way to prevent this?
onPause is part of the Activity lifecycle, which relates to the different states an Activity goes through - it's not about whether your app as a whole is in the background. Here's what the docs say about it
The system calls this method as the first indication that the user
is leaving your activity (though it does not always mean the activity is being destroyed); it indicates that the activity is no longer in the foreground (though it may still be visible if the user is in multi-window mode).
There are a few ways you could handle it - the simplest would be to have a navigating flag you set when you're switching to activity B. Then the onPause can check that flag, and skip setting you to offline if there's a navigation even going on.
I'm assuming you mean the dot is flashing for other users (since you wouldn't be looking at the same View if you're the one switching between activities) - it might actually be a good idea to have the app send out an "I'm online" ping every so often anyway.
That way they can set a user to offline if they don't get a message after a certain amount of time - it just means that if a user gets a crash, their network drops or whatever, they don't look online the whole time just because they didn't send an "I'm offline now" message through onPause
I have a timer that talks to java objects through LS2J. It has only to call some getters of the java objects and to update the GUI with new values. This causes the GUI in iNotes Client to show the "Busy" cursor very shortly when the timer ticks. I is really annoying because it occurs even when another window is open and even in the designer.
I actually have to expect that the functionality in the timer event will get more complicated in the future, so I don't want to solve the problem by making my handler lighter.
Is there a way to tell iNotes client not to show this cursor or even an alternative way to make this regular check without timers?
The NotesTimer class in Notes client (not iNotes) does take over the foreground when it triggers, so there will be a bit of a delay if you do something that takes time to execute. It's possible to set up the Notes client to execute background scheduled agents in local database replicas, so that might be an option. You can to the heavy lifting in background and deposit the results somewhere -- say, in a profile document -- that can be accessed quickly by the UI code.
Alternately, you could try a XPages in the client application. I believe it can do partial refreshes while other stuff is going on.
For the record, I simplified the functionality of the Java call by preparing the data so that the timer only has to read the results. I also made the timer run every 3 seconds instead of 1.
Now I don't see any flicker!
Subject sounds mutually exclusive, and this is probably a terrible hack, but I'll ask anyway.
I have an single-threaded VB.NET application which is setting status bar label to "Loading..." and then synchronously loading data from database which in some cases can take up to 1-2 minutes. Is there any way to show user an AJAX-type animation while data is being loaded? Of course, the correct way is to use separate thread/BackgroundWorker for data access and manage UI separately, but I can't currently change data access model and have been asked for a "temporary fix".
Here are some of my ideas at the moment:
Update label (and only that single label) from another thread, force it's redraw, somehow circumventing windows forms message pump (probably not possible)
Keep another process in background and send "show" message to it from main application. It shows up in front of application, shows animation until "hide" message from main application is received. (problems with user switching away from main application but "animation" form still visible)
I'll probably get down voted for suggesting it (and quite frankly I don't blame people) but this sounds like a job for DoEvents.
I wouldn't normally suggest it, but you are looking for a hack.
When my application loads, using the didFinishLaunchingWithOptionsi parse data from the internet to nsarrays. My question is, when the user exists the application by using the 'home' button, and then loads the application again how can the data be re-loaded? (because if the data does not reload - if there are any updates on websites, the new updates will not be seen).
Add an applicationWillEnterForeground method to your app delegate. Load the data there, or start a thread to load it if you like.
You should probably also periodically check for new data even while the app remains open, because the user could go idle for a long time.
As an aside, you shouldn't do anything which might block in applicationDidFinishLaunchingWithOptions. If you are using synchronous NSURLConnection APIs there is a danger the OS might kill your app for taking too long to launch. Best to either use the asynchronous/NSURLConnectionDelegate APIs or do the networking on a background thread and call back to the main thread when you need to update UI (UIKit does NOT like being called from background threads, as it is not thread safe. It might appear to work sometimes, but it will come back to bite you sooner or later).
In an iOS app, I'm writing a class that will be messaged, go do a background request (via performSelectorInBackground:withObject:), and then return the result through a delegate method (that will then be displayed on a map). Everything seems to work right when one request is happening at a time, but I'm trying to figure out how to handle multiple overlapping requests. For example, if a user enters something in a search box that starts a background thread, and then enters something else before the initial background thread completes, how should this be handled?
There are a few options (don't let the second request start while the first is in progress, stop the first as soon as the second is requested, let both run simultaneously and return independent results, etc.), but is there a common/recommended way to deal with this?
I don't think there's universal answer to this. My suggestion is to separate tasks (in form of NSOperations and/or blocks) by their function and relationships between them.
Example: you don't want add image resizing operation to the same queue with fetching some unrelated feed from web, especially if no relationship between them exists. Or maybe you do because both require great amount of memory and because of that can't run in parallel.
But you'd probably want to add web image search operations to same queue while canceling operations of the same type added to this queue before. Each of those image search operations might init image resize operation and place it into some other queue. Now you have an relationship and have to cancel resizing in addition to image search operation. What if image search operation takes longer than associated resize operation? How do you keep a reference to it or know when it's done?
Yeah, it gets complicated easily and sorry if I didn't give you any concrete answers because of uniqueness of each situation but making it run like a Swiss clock in the end is very satisfying :)