Download presentation
Presentation is loading. Please wait.
Published byDominic Maxwell Modified over 6 years ago
1
Background Service in UWP and on iOS and Android with Xamarin
NET433 Alec Tucker
2
Agenda Background Tasks vs Threading
4/20/2018 1:11 AM Agenda Background Tasks vs Threading What’s Supported on Each Platform? UWP iOS (Xamarin) Android (Xamarin) © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
3
Background Tasks vs Threading
4/20/2018 1:11 AM Background Tasks vs Threading Threading to avoid blocking the UI Critical for any “heavy” processing, comms, etc Users expect a consistently responsive UI Async..await provided by .Net and fully supported by Xamarin across all platforms Running to completion when the app is closed Exact mechanics and level of support vary by platform. © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
4
What’s Supported on Each Platform
4/20/2018 1:11 AM What’s Supported on Each Platform Common Concepts First, some definitions “Tasks” in this talk refer to defined processes, rather than System.Threading.Tasks Foreground App The app currently on display and taking the user’s attention By design, this gets the lion’s share of resources Suspended App Apps are suspended when another app demands the user’s attention (e.g. an incoming phone call) Typically remain in memory, but get little love Time to perform some housekeeping – usually saving state Background App An app that’s running in the background © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
5
UWP Background Tasks Microsoft Ignite 2016 4/20/2018 1:11 AM
© 2016 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
6
4/20/2018 1:11 AM Windows Phone 8 gave us: private void Application_Launching(object sender, LaunchingEventArgs e) { // Called when the application is launching. Executed once } private void Application_Activated(object sender, ActivatedEventArgs e) // Called when the application is activated. Not called on first launch. private void Application_Deactivated(object sender, DeactivatedEventArgs e) // Called when the application is send to the background private void Application_Closing(object sender, ClosingEventArgs e) // Called when the application is closing. (Not called when deactivating) © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
7
Windows 10 uses: this.Suspending += (s, e) => {
4/20/2018 1:11 AM Windows 10 uses: this.Suspending += (s, e) => { // Execute code, e.g. to save state }; this.Resuming += (s, e) => // Execute code, e.g. to load state © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
8
Extended Execution vs Background Task
4/20/2018 1:11 AM Extended Execution vs Background Task © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
9
Extended Execution Request permission Two types:
4/20/2018 1:11 AM Extended Execution Request permission Two types: One allows a little extra time to do something during app suspension (if permission granted) The other lets the OS know this is a special kind of app which needs to run indefinitely Neither type has any UI © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
10
private async void OnSuspending(object sender, SuspendingEventArgs e)
4/20/2018 1:11 AM private async void OnSuspending(object sender, SuspendingEventArgs e) { var deferral = e.SuspendingOperation.GetDeferral(); using (ExtendedExecutionSession session = new ExtendedExecutionSession() Reason = ExtendedExecutionReason.SavingData, Description = "Saving data" }) session.Revoked += (s, e) => // Tidy up }; switch(await session.RequestExtensionAsync()) case ExtendedExecutionResult.Allowed: // Permission for extended execution has been granted. Save all data. await SendAllData(); break; case ExtendedExecutionResult.Denied: // Permission for extended execution has been denied. Save summary // data only as we have limited time. await SendSummaryData(); } deferral.Complete(); © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
11
ExtendedExecutionSession session = null;
4/20/2018 1:11 AM ExtendedExecutionSession session = null; public async Task RunBackgroundTask() { if (session == null) session = new ExtendedExecutionSession() Reason = ExtendedExecutionReason.SavingData, Description = "Saving data" }; session.Revoked += (s, e) => // Tidy up switch (await session.RequestExtensionAsync()) case ExtendedExecutionResult.Allowed: // Permission for extended execution has been granted. Save all data. await SendAllData(); break; case ExtendedExecutionResult.Denied: // Permission for extended execution has been denied. Save summary // data only as we have limited time. await SendSummaryData(); } © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
12
Extended Execution vs Background Task
4/20/2018 1:11 AM Extended Execution vs Background Task © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
13
Background Tasks Background tasks can be initiated by system events
4/20/2018 1:11 AM Invalid SmsReceived UserPresent UserAway NetworkStateChange ControlChannelReset InternetAvailable SessionConnected ServicingComplete LockScreenApplicationAdded LockScreenApplicationRemoved TimeZoneChange OnlineIdConnectedStateChange BackgroundWorkCostChange PowerStateChange Background Tasks Background tasks can be initiated by system events Code needs to be registered with system events, or triggers Available triggers are defined in the SystemTriggerType enum © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
14
4/20/2018 1:11 AM public class BackgroundTask : IBackgroundTask { private BackgroundTaskCancellationReason cancelReason = BackgroundTaskCancellationReason.Abort; private bool isCancelRequested = false; private BackgroundTaskDeferral deferral = null; public async void Run(IBackgroundTaskInstance taskInstance) try // Get the deferral object from the task instance deferral = taskInstance.GetDeferral(); // Wire up a task cancellation handler taskInstance.Canceled += (IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason) => isCancelRequested = true; cancelReason = reason; }; // Check BackgroundWorkCost // If High, then do as little work as possible and return, // otherwise proceed as planned switch (BackgroundWorkCost.CurrentBackgroundWorkCost) { case BackgroundWorkCostValue.High: // Perform only critical operations await PerformOnlyHighPriorityOperations(); break; case BackgroundWorkCostValue.Medium: // Perform critical and medium priority operations await PerformHighAndMediumPriorityOperations(); case BackgroundWorkCostValue.Low: // Proceed with ALL desired processing await PerformAllOperations(); } catch (Exception ex) // Handle the exception finally if (deferral != null) deferral.Complete(); © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
15
InternetNotAvailable SessionConnected SessionDisconnected
4/20/2018 1:11 AM KeyValuePair<Guid, IBackgroundTaskRegistration>? task = (from t in BackgroundTaskRegistration.AllTasks where t.Value.Name == taskName select t).FirstOrDefault<KeyValuePair<Guid, IBackgroundTaskRegistration>>(); if (!task.HasValue) { // Task is not already registered BackgroundTaskBuilder builder = new BackgroundTaskBuilder() Name = taskName, TaskEntryPoint = ”Ignite2017.BackgroundTask" }; builder.SetTrigger(new SystemTrigger(SystemTriggerType.InternetAvailable, false)); builder.AddCondition(new SystemCondition(SystemConditionType.FreeNetworkAvailable)); builder.AddCondition(new SystemCondition(SystemConditionType.UserPresent)); BackgroundTaskRegistration backgroundTask = builder.Register(); } Invalid UserPresent UserNotPresent InternetAvailable InternetNotAvailable SessionConnected SessionDisconnected FreeNetworkAvailable BackgroundWorkCostNotHigh © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
16
backgroundTask.Completed +=
4/20/2018 1:11 AM backgroundTask.Completed += (BackgroundTaskRegistration sender, BackgroundTaskCompletedEventArgs e) => { string taskId = sender.TaskId.ToString(); // Do what you need to with the results }; © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
17
iOS with Xamarin Background Tasks Microsoft Ignite 2016
© 2016 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
18
iOS Supports Five App States
4/20/2018 1:11 AM iOS Supports Five App States Not running This is as it sounds – the app is not running. It’s not been launched, or it’s been completely terminated. Inactive An inactive app is currently running, but is not receiving events. Apps transition through this state quickly. Active The app can be considered the current foreground app as per the earlier definitions. It currently has the user’s attention, and has as much access to the hardware resources of the device as is possible. Background The app is currently running as a registered background app, which means it’s running within the constraints described shortly. Multiple apps can be in this state. Suspended A suspend app resides in memory, but is not currently running. © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
19
4/20/2018 1:11 AM iOS Lifecycle iOS will call the following methods in your AppDelegate.cs. Override these if you want to perform specific tasks as the state changes / is about to change. iOS Delegate Xamarin.iOS Description willFinishLaunchingWithOptions WillFinishLaunching First method to be called. First opportunity for you to execute code at launch time didFinishLaunchingWithOptions FinshedLaunching Typically where initialisation stuff goes (e.g. Xamarin.Forms). You have 17 seconds. applicationDidBecomeInactive OnActivated App is about to transaction to Active and become the Foreground App applicationWillResignActive OnResignActivation App is transitioning out of the Active state applicationDidEnterBackground DidEnterBackground App has entered the Background state applicationWillEnterForeground WillEnterForeground App is transitioning from Background into the foreground, but it’s not yet Active applicationWillTerminate WillTerminate That’s all folks. If your app was already suspended it can be terminated without warning / calling this © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
20
iOS Provides Three Options
4/20/2018 1:11 AM iOS Provides Three Options Finite Length Tasks Have a fixed amount of time in which to complete, but do not impose restrictions on the code you can run. If it finishes in time, great. If not, it will be shut down anyway. Long Running Tasks Can continue without time limitations, but support only a finite set of operations, specifically: Playing or recording audible content, location tracking VoIP, regular comms with accessories, incl Bluetooth LE, background fetch operations and remote notifications Downloading Content Designed for data transfer. Not time restricted. Can continue while your app is suspended or terminated. Will wake your app up and notify it on completion. © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
21
iOS – Finite Length Tasks
4/20/2018 1:11 AM iOS – Finite Length Tasks Time constrained, NOT resource constrained Start with: var taskId = UIApplication.BeginBackgroundTask( OnExpiry ); Query time remaining with: UIApplication.SharedApplication.BackgroundTimeRemaining Critical step – end the task: UIApplication.SharedApplication.EndBackgroundTask( taskId ); © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
22
iOS – Finite Length Tasks
4/20/2018 1:11 AM iOS – Finite Length Tasks Call EndBackgroundTask when: The task completes successfully The task is cancelled The task expires The app comes back into the foreground © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
23
4/20/2018 1:11 AM public async Task LaunchBackgroundTask() {
nint taskId = -1; CancellationTokenSource token = new CancellationTokenSource(); // 1. Begin the background task taskId = UIApplication.SharedApplication.BeginBackgroundTask(() => // Handle task expiry here }); // 2. Perform background processing await Task.Run(() => try // Perform processing on background thread if (token.IsCancellationRequested) // Handle the cancellation request and clean up resources // ... // Alternatively (or additionally), throw and catch a // specific type of exception token.Token.ThrowIfCancellationRequested(); } catch (OperationCanceledException ocEx) // Handle task cancellation here , token.Token ); // 3. End the background task UIApplication.SharedApplication.EndBackgroundTask(taskId); public override void WillEnterForeground(UIApplication uiApplication) { if (taskId != -1) UIApplication.SharedApplication.EndBackgroundTask(taskId); } base.WillEnterForeground(uiApplication); © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
24
iOS – Long Running Tasks
4/20/2018 1:11 AM iOS – Long Running Tasks Resource / operation constrained, NOT time constrained Info.plist entries: <key>UIBackgroundModes</key> <array> <string>audio</string> <string>location</string> <string>voip</string> <string>newsstand-content</string> <string>external-accessory</string> <string>bluetooth-central</string> <string>bluetooth-peripheral</string> <string>fetch</string> <string>remote-notification</string> </array> © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
25
iOS – Long Running Tasks
4/20/2018 1:11 AM iOS – Long Running Tasks Audio Media framework prevents app suspension while media content is being played or recorded. When this stops, iOS proceeds with suspension. VoIP Suspension not prevented. iOS monitors sockets for these apps and brings them out of suspension when inbound comms are detected. Fetch iOS can check for new content. It will determine when this happens, and it might never happen. © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
26
iOS – Long Running Tasks - Fetch
4/20/2018 1:11 AM iOS – Long Running Tasks - Fetch public override async void PerformFetch( UIApplication application, Action<UIBackgroundFetchResult> completionHandler) { // Declare fetch result, and set default value... UIBackgroundFetchResult fetchResult = UIBackgroundFetchResult.NoData; try // Fetch your data. If successful then set... fetchResult = UIBackgroundFetchResult.NewData; } catch // Handle the error, and set... fetchResult = UIBackgroundFetchResult.Failed; finally // Be sure to call the completion handler when we've finished completionHandler(fetchResult); © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
27
iOS – Long Running Tasks - Fetch
4/20/2018 1:11 AM iOS – Long Running Tasks - Fetch You can exert some control over the frequency of fetch attempts: UIApplication.SharedApplication.SetMinimumBackgroundFetchInterval(1800); Two constants you can make use of: UIKit.UIApplication.BackgroundFetchIntervalMinimum UIKit.UIApplication.BackgroundFetchIntervalNever © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
28
Android with Xamarin Background Tasks Microsoft Ignite 2016
© 2016 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
29
Android Supports Four App States
4/20/2018 1:11 AM Android Supports Four App States Running When an activity is opened by a user Paused When the activity view is completely or partially obscured. Backgrounded When the home button is pressed, or when the app switcher button is pressed. The app remains in memory in this state. Stopped When the back button is pressed, or when memory is low. The app is removed from memory in this state. © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
30
Android Lifecycle We’re able to override the following: OnCreate()
4/20/2018 1:11 AM Android Lifecycle We’re able to override the following: OnCreate() OnStart() OnPause() OnResume() OnStop() OnRestart() OnDestroy() © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
31
Android Lifecycle Action Calls Launch app OnCreate() OnStart()
4/20/2018 1:11 AM Android Lifecycle Action Calls Launch app OnCreate() OnStart() OnResume() Pause app OnPause() Resume paused app Background the app OnStop() Restart backgrounded app OnRestart() Stop backgrounded app OnDestroy() © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
32
4/20/2018 1:11 AM Android Services An application component that can perform long running tasks without a UI [Android.App.Service] public class MyAndroidService : Android.App.Service { public override Android.OS.IBinder OnBind(Android.Content.Intent intent) throw new System.NotImplementedException(); } As resources dwindle, Android will go on the hunt for things to kill, starting with activities and moving on to services. If the OS does kill your service, you can configure it to restart once sufficient resources become available © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
33
Android Services Services should not be started like this:
4/20/2018 1:11 AM Android Services Services should not be started like this: MyAndroidService service = new MyAndroidService(); Rather they should be started via an Intent. [Android.App.Service] public class MyAndroidService : Android.App.Service { public override Android.App.StartCommandResult OnStartCommand( Android.Content.Intent intent, Android.App.StartCommandFlags flags, int startId) return base.OnStartCommand(intent, flags, startId); } public override Android.OS.IBinder OnBind(Android.Content.Intent intent) throw new System.NotImplementedException(); © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
34
Android Services Value Action NotSticky
4/20/2018 1:11 AM Android Services StartCommandResult will contain one of the following values: Value Action NotSticky Service will not be restarted if killed. Typical for processes that can be retried without adverse impact, e.g. periodic checking a web service for data updates RedeliverIntent If killed, this service will be scheduled to be restarted, and the last delivered intent will be redelivered Sticky Restart if killed. No intent will be passed in StickyCompatibility A compatibility version of Sticky for older versions (older than API15). Does not guarantee that OnStartCommand will be called It’s important that OnStartCommand returns one of these values as quickly as possible. This means that you’ll need to start a separate thread within your service. © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
35
Android Services So to start and stop your services, use: For example:
context.StartService() contect.StopService() For example: StartService(new Android.Content.Intent(this, typeof(MyAndroidService))); StopService(new Android.Content.Intent(this, typeof(myAndroidService))); Services can also stop themselves using: this.StopSelf() © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
36
Android Services - Binding
4/20/2018 1:11 AM Android Services - Binding What about background services that interact with the UI of your app? Android lets us bind to a service It will shut down the service when all clients have unbound Hybrid – common use. Example: An app that tracks location and shows location info in the UI Start the service when the app is launched Communicate with it Leave it running when the app is terminated © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
37
4/20/2018 1:11 AM public class TimeTrackingServiceBinder : Binder {
public TimeTrackingService Service { get; private set; } public TimeTrackingServiceBinder(TimeTrackingService pService) this.Service = pService; } public class TimeTrackingService : Service { // Declare a timer which will fire every minute private Timer TimeTracker = new Timer(60000); public EventHandler<ElapsedEventArgs> TimerElapsed; public override Android.OS.IBinder OnBind(Android.Content.Intent intent) return new TimeTrackingServiceBinder(this); } public override StartCommandResult OnStartCommand( Android.Content.Intent intent, StartCommandFlags flags, int startId) TimeTracker.Elapsed += TimeTracker_Elapsed; TimeTracker.Start(); return StartCommandResult.Sticky; public override void OnDestroy() TimeTracker.Elapsed -= TimeTracker_Elapsed; base.OnDestroy(); private void TimeTracker_Elapsed(object sender, ElapsedEventArgs e) this.TimerElapsed(this, e); © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
38
4/20/2018 1:11 AM public class TimeTrackingServiceConnection : IServiceConnection { public void OnServiceConnected(ComponentName name, Android.OS.IBinder service) throw new System.NotImplementedException(); } public void OnServiceDisconnected(ComponentName name) public System.IntPtr Handle get { throw new System.NotImplementedException(); } public void Dispose() © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
39
4/20/2018 1:11 AM public class TimeTrackingServiceConnection : Java.Lang.Object, IServiceConnection { private IBinder binder; public event EventHandler<ServiceEventArgs> ConnectionChanged = delegate { }; public TimeTrackingService Service get TimeTrackingServiceBinder serviceBinder = binder as TimeTrackingServiceBinder; return serviceBinder != null ? serviceBinder.Service : null; } public void OnServiceConnected(ComponentName name, Android.OS.IBinder service) = service as TimeTrackingServiceBinder; if (serviceBinder != null) this.binder = serviceBinder; ConnectionChanged(this, new ServiceEventArgs(true)); public void OnServiceDisconnected(ComponentName name) ConnectionChanged(this, new ServiceEventArgs(false)); this.binder = null; public class ServiceEventArgs : EventArgs { public bool IsConnected { get; private set; } public ServiceEventArgs(bool pIsConnected) IsConnected = pIsConnected; } © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
40
4/20/2018 1:11 AM public class ServiceManager {
private static Lazy<ServiceManager> serviceManager = new Lazy<ServiceManager>(() => new ServiceManager()); public static ServiceManager Current get { return serviceManager.Value; } } private TimeTrackingServiceConnection serviceConnection; public TimeTrackingService TimeTrackingService get return serviceConnection.Service; public event EventHandler<ServiceEventArgs> ConnectionChanged = delegate { }; private ServiceManager() Task.Run(() => Intent intent = new Intent( Application.Context, typeof (TimeTrackingService)); // Start the service... Application.Context.StartService(intent); // ...and bind to it serviceConnection = new TimeTrackingServiceConnection(); serviceConnection.ConnectionChanged += (s, e) => ConnectionChanged(this, e); Application.Context.BindService( intent, serviceConnection, Bind.AutoCreate); }); © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
41
ServiceManager.Current.ConnectionChanged += (s, e) => {
4/20/2018 1:11 AM ServiceManager.Current.ConnectionChanged += (s, e) => { if (e.IsConnected) ServiceManager.Current.TimeTrackingService.TimerElapsed += OnTimerElapsed; } else ServiceManager.Current.TimeTrackingService.TimerElapsed -= OnTimerElapsed; }; private void OnTimerElapsed(object sender, System.Timers.ElapsedEventArgs e) // Do something here with e © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
42
Android Services Lifecycle Event Action OnCreate
4/20/2018 1:11 AM Android Services Finally, we should also be doing the following: Lifecycle Event Action OnCreate Wire up the ConnectionChanged event on the previous slide OnPause Unwire the TimerElapsed event to prevent it from firing OnRestart Wire the TimerElapsed event up again © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
43
Summary UWP iOS (Xamarin) Android (Xamarin)
Extended Processing vs Background Tasks iOS (Xamarin) Finite Length Tasks vs Long Running Tasks Android (Xamarin) Android Services and Binding © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
44
Continue your Ignite learning path
4/20/2018 1:11 AM Continue your Ignite learning path Visit Channel 9 to access a wide range of Microsoft training and event recordings Head to the TechNet Eval Centre to download trials of the latest Microsoft products Visit Microsoft Virtual Academy for free online training visit © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
45
Thank you Chat with me in the Speaker Lounge Find me @alecdtucker
4/20/2018 1:11 AM Thank you Chat with me in the Speaker Lounge Find © 2014 Microsoft Corporation. All rights reserved. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.