EvenTiles from Start to Finish - Part 12
Join the DZone community and get the full member experience.
Join For Freein the previous episode of this series about how to develop a windows phone application from scratch we talked about debugging a periodictask . before digging deeper into exchanging data between an application and its periodictask, we need to talk a little more about scheduling the periodictask and about expiration of a periodictask.
going back to part 10 of the eventiles series , the periodictask was created inside the mainpage.xaml.cs file in a method called startperiodicagent. this private method takes care of stopping a currently active agent before creating a new one. it also handles an exception that might be thrown when an attempt is made to start a new periodictask while the user has disabled background processing for the eventiles application, which they can do from inside the phone settings.
however, after submitting eventiles to marketplace, i noticed an
exceptionally high crash count in the application (as you can see from
my apphub dashboard). since i want to share all details about developing
this application, but also about the application’s life cycle, it is
only fair to share the number of crashes to date, a number i am not
proud off.
for starters, the first version of eventiles called
launchfortest
in release mode which results in a thrown exception as shows up in the
call stack of various crash incidents. also, the application does not
count on other applications making use of background agents on a
particular device. to preserve memory, but mainly battery power on the
device, the number of background agents that can run at the same time is
limited. it varies depending on the hardware capabilities of the device
and might differ between devices, but it is a small number and
therefore the limit can easily be reached. when this limit is reached, a
schedulerserviceexception
will be thrown whenever you attempt to add a periodic task. of course
you much handle this exception to prevent your application against
crashing, since you are adding your periodic task from inside your
application.
so, to create a periodic task, the following code should be used (which is an extension to the code that we used in
part 10 of the series
):
correctly adding the agent:
private void startperiodicagent() { removeperiodicagent(); var eventilesperiodictask = new periodictask(eventilesperiodictaskname); eventilesperiodictask.description = "eventilesperiodictask"; try { scheduledactionservice.add(eventilesperiodictask); #if debug_task scheduledactionservice.launchfortest(eventilesperiodictaskname, timespan.fromseconds(30)); #endif app.periodictaskscheduled = true; } catch (invalidoperationexception ex) { if (ex.message.contains("bns error: the action is disabled")) { messagebox.show("background agents for this application are disabled."); } } catch (schedulerserviceexception) { messagebox.show("can't schedule your background agent. there might be too many background agents enabled. you can disable background agents through the phone's settings application."); } }
if you take a look at how a periodic task is created you will also see that a app.periodictaskscheduled is set to true . this static property is maintained in the app.xaml.cs file, its value is stored / retrieved from the isolatedstoragesettings ( see part 5 of eventiles for more information).
the reason to add this boolean property is to find out if the
application did schedule a periodictask. if a periodictask was added for
the application, you must realize that the periodictask will age and
eventually it will expire unless it is rescheduled by the application. a
periodictask will expire if it has not been rescheduled for 14 days
from the time it was scheduled. since the application is responsible for
adding a periodictask, it means that the periodictask will only
continue to run if the application is activated at least once every two
weeks and if the application makes sure to reschedule the periodictask.
the approach that eventiles takes right now is to check if at some time a
periodictask was scheduled. if so, it will be rescheduled as soon as
the eventiles’ mainpage is created.
note: we could have used another way to determine if a periodictask was scheduled, for instance by verifying if a secondarytile is currently available on the startscreen.
making use of isolatedstoragesettings, we will add logic to the
app.xaml.cs file to properly store and retrieve the
app.periodictaskscheduled property when the application is started,
activated, deactivated and terminated.
to begin, a new property and a new const string to identify the value
in the isoloatedstoragesettings are created in app.xaml.cs as follows:
public const string keyptscheduled = "k_pts"; public static bool periodictaskscheduled { get; set; }
in the constructor, the
periodictaskscheduled
property is explicitly initialized to
false
. finally, the value of periodictaskscheduled is stored / retrieved in the various application life cycle events:
store/retrieve property value:
// code to execute when the application is launching (eg, from start) // this code will not execute when the application is reactivated private void application_launching(object sender, launchingeventargs e) { if (appsettings.contains(keyptscheduled)) { periodictaskscheduled = (bool)appsettings[keyptscheduled]; } if (!appsettings.contains(keyactsecbackcontent)) { appsettings[keyactsecbackcontent] = defaultsecbackcontent; } actualsecbackcontent = (string)appsettings[keyactsecbackcontent]; } // code to execute when the application is activated (brought to foreground) // this code will not execute when the application is first launched private void application_activated(object sender, activatedeventargs e) { if (!e.isapplicationinstancepreserved) { periodictaskscheduled = (bool)appsettings[keyptscheduled]; actualsecbackcontent = (string)appsettings[keyactsecbackcontent]; } } // code to execute when the application is deactivated (sent to background) // this code will not execute when the application is closing private void application_deactivated(object sender, deactivatedeventargs e) { appsettings[keyptscheduled] = periodictaskscheduled; appsettings[keyactsecbackcontent] = actualsecbackcontent; } // code to execute when the application is closing (eg, user hit back) // this code will not execute when the application is deactivated private void application_closing(object sender, closingeventargs e) { appsettings[keyptscheduled] = periodictaskscheduled; appsettings[keyactsecbackcontent] = actualsecbackcontent; }
finally, we will use this property inside the mainpage.xaml.cs file
when the page is constructed to determine if we need to reschedule a
periodictask:
rescheduling periodictask?
public mainpage() { initializecomponent(); if (app.periodictaskscheduled) { startperiodicagent(); } }
each time the periodictask is scheduled, the
app.periodictaskproperty
is set to
true
and a secondary tile is created. if the secondary tile is removed, the
app.periodictaskproperty
is set to
false
as well.
the following video shows you how to modify the existing eventiles
project to improve the way the periodictask is scheduled as well as the
functionality needed to reschedule the periodictask:
if you want to take a look at the source code that we have available
for eventiles so far, you can download the entire solution belonging to
this episode:
download eventiles episode 12 source code
after downloading and unzipping the sample code, you can open the eventiles solution in visual studio 2010 express for windows phone. you must have the windows phone sdk 7.1 installed on your development system to do so. if you have a developer unlocked phone you can deploy the application to your phone, if you don’t have a developer unlocked phone you can still experiment with this application inside the emulator.
if
you want to see eventiles already in action on your windows phone, you
can also install the latest version from marketplace. remember that this
application is not meant to be extremely useful, although it contains
similar functionality that “serious” applications have. just go ahead
and get your free copy of eventiles from marketplace at this location:
http://www.windowsphone.com/en-us/search?q=eventiles
(or search on your phone for eventiles in the marketplace application).
when eventiles continues with part 13, you will learn how to exchange data between an application and its background agent.
source: http://mstruys.com/2012/01/05/eventiles-from-start-to-finishpart-12/
Opinions expressed by DZone contributors are their own.
Comments