小夢今天給大家分享一下windows phone 8.1中的后台任務如何實現,許多應用都會用到后台任務,所以我們必須得掌握.
新建后台任務類:
首先我們先新建一個windows phone 8.1空白應用程序.然后請右鍵單擊你的解決方案並依此選擇“添加”->“新建項目”.選擇 Windows 運行時組件項目類型,為該項目命名為Basktask.(名字都隨便起了,只是為了后面方便)
在項目中,右鍵單擊“引用”並選擇“添加新引用”。在“解決方案”下,選擇“項目”,然后選擇Basktask.
將Basktask默認生成的類class1改為SimpleTask.並實現IBackgroundTask接口,在類中實現繼承自接口的Run方法.
Run 方法是一個需要的入口點,當觸發指定事件時,將調用該入口點;每個后台任務都需要該方法。
1 namespace Basktask 2 { 3 public sealed class SimpleTask:IBackgroundTask 4 { 5 public void Run(IBackgroundTaskInstance taskInstance)//后台任務入口 6 { 7 //后台需要執行的操作 8 } 9 }
如果你在后台任務中運行任何異步代碼,則你的后台任務需要使用延遲。如果不使用延遲,則后台任務進程可能會意外終止(如果 Run 方法在完成異步方法調用之前完成)。調用異步方法之前,在 Run 方法中請求延遲。將延遲保存到某個全局變量以便可以從異步方法訪問。完成異步代碼之后聲明延遲完成。 以下示例代碼獲取和保存延遲,並在異步代碼完成后將其釋放:
1 public void Run(IBackgroundTaskInstance taskInstance)//后台任務入口 2 { 3 4 deferral = taskInstance.GetDeferral(); 5 6 deferral.Complete(); 7 }
創建觸發器對象
為了使得后台任務能夠響應事件觸發,我們需要注冊觸發器,當條件滿足觸發器被觸發的時候,后台任務就會被執行.windows phone 8.1后台任務可以使用的觸發器有SystemTrigger,TimeTrigger,LocationTrigger,
MaintenanceTrigger PushNotificationTrigger RfcommConnectionTrigger DeviceChangeTrigger
BluetoothSignalStrengthTrigger GattCharacteristicNotificationTrigger.
下面我們簡單介紹一下:
SystemTrigger:
SystemTrigger是系統事件觸發器,以下事件會引發該觸發器:UserPresent/Away, NetworkStateChange, InternetAvailable, SessionConnected, ServicingComplete, TimeZoneChange 等
注:LockScreenApplicationAdded and LockScreenApplicationRemoved 在windows phone 8.1中不在支持.
用法如下:
第一個參數 triggerType 指定了將激活此后台任務的系統事件觸發器的類型。第二個參數 OneShot 指定后台任務是否將在下次發生系統事件並觸發后台任務時,或在每次系統事件發生時運行一次,直至任務注銷為止。
1 SystemTrigger systemTrigger = new SystemTrigger(SystemTriggerType.InternetAvailable, false);
TimeTrigger:
如果后台任務需要周期性運行可以使用TimeTrigger .用法如下:
1 TimeTrigger timetrigger = new TimeTrigger(30, false);
注:最小時間間隔為 30分鍾.
第二個參數 OneShot 指定后台任務是運行一次還是保持周期性運行。如果 OneShot 被設置為 true,則第一個參數 (FreshnessTime) 會指定在計划后台任務之前需等待的分鍾數。如果 OneShot 被設置為 false,則 FreshnessTime 會指定后台任務的運行頻率。
其余的觸發器大家可以參考MSDN文檔,用法都很簡單.
創建后台任務對象:
1 var SampleTask = new BackgroundTaskBuilder(); //創建后台任務實例 2 SampleTask.Name = "SimpleBackTask"; //指定后台任務名稱 3 SampleTask.TaskEntryPoint = "Basktask.SimpleTask";//指定后台任務名稱 4 SampleTask.SetTrigger(timetrigger);//指定后台任務的觸發器
添加后台任務運行條件(可選)
在觸發器事件發生后,你可以添加條件控制任務何時運行。添加該條件之前,創建一個代表該條件的 SystemCondition 對象,該對象必須實際用於運行后台任務。在構造函數中,通過提供一個 SystemConditionType 枚舉值指定必須滿足的條件。
1 SystemCondition internetCondition = new SystemCondition(SystemConditionType.InternetAvailable); 2 SampleTask.AddCondition(internetCondition);
注冊后台任務:
1 var access = await BackgroundExecutionManager.RequestAccessAsync(); 2 if (access == BackgroundAccessStatus.AllowedMayUseActiveRealTimeConnectivity) 3 { 4 BackgroundTaskRegistration task = SampleTask.Register(); 5 } 6 else if (access == BackgroundAccessStatus.Denied) 7 { 8 await new MessageDialog("您已禁用后台任務或后台任務數量已達最大!").ShowAsync(); 9 }
注:在 windows phone 8.1中,注冊后台任務之前必須調用RequestAccessAsync()方法!
在應用清單中生命后台任務:
后台任務調試:
若要調試后台任務,請在該任務的 Run 方法中設置一個斷點。 在“調試位置”工具欄中,選擇你的后台任務。這將導致系統立即調用 Run 方法。
- 在該任務的 Run 方法中設置一個斷點。
- 按 F5 或點擊“調試”>“啟動調試”以部署和運行該應用。
- 應用啟動后,切換回 Visual Studio。
- 確保顯示“調試位置”工具欄。該工具欄位於“查看”>“工具欄”菜單。
- 在“調試位置”工具欄上,單擊“掛起”下拉菜單,然后選擇你的后台任務.
- Visual Studio 會在斷點位置掛起執行。
- 按 F5 點擊“調試”>“繼續”以繼續運行該應用。
- 按 Shift+F5 或點擊“調試”>“停止調試”以停止調試。
下面我們來看一個實例:
1 namespace Basktask 2 { 3 public sealed class SimpleTask:IBackgroundTask 4 { 5 bool cancelRequested = false;// 用來表示是否已經請求取消后台任務 6 BackgroundTaskDeferral deferral = null;//后台任務的延時 7 ThreadPoolTimer periodicTimer = null;//計時器 8 uint progress = 0; //用於保存后台任務的進度 9 IBackgroundTaskInstance bTaskInstance = null;//提供對后台實例的訪問 10 11 public void Run(IBackgroundTaskInstance taskInstance)//后台任務入口 12 { 13 taskInstance.Canceled += taskInstance_Canceled; 14 deferral = taskInstance.GetDeferral(); 15 bTaskInstance = taskInstance; 16 periodicTimer = ThreadPoolTimer.CreatePeriodicTimer(new TimerElapsedHandler(PeriodicTimerCallback), TimeSpan.FromMinutes(5)); 17 18 } 19 20 private void PeriodicTimerCallback(ThreadPoolTimer timer) 21 { 22 if ((cancelRequested==false)&&(progress<100)) 23 { 24 progress += 10; 25 bTaskInstance.Progress = progress; 26 } 27 else 28 { 29 periodicTimer.Cancel(); 30 var settings = Windows.Storage.ApplicationData.Current.LocalSettings; 31 var key = bTaskInstance.Task.Name; 32 settings.Values[key] = (progress < 100) ? "Canceled" : "Completed"; 33 deferral.Complete(); 34 } 35 } 36 37 void taskInstance_Canceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason) 38 { 39 cancelRequested = true; 40 } 41 } 42 }
1 protected override void OnNavigatedTo(NavigationEventArgs e) 2 { 3 foreach (var task in BackgroundTaskRegistration.AllTasks) 4 { 5 if (task.Value.Name == "SimpleBackTask") 6 { 7 task.Value.Progress += Value_Progress; 8 task.Value.Completed += Value_Completed; 9 UpdateUI("后台任務已經存在",""); 10 } 11 } 12 } 13 14 private async void UpdateUI(string p1, string p2)//更新UI 15 { 16 await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => 17 { 18 progressText.Text = p1; 19 statusText.Text = p2; 20 }); 21 } 22 //處理后台任務完成事件 23 void Value_Completed(BackgroundTaskRegistration sender, BackgroundTaskCompletedEventArgs args) 24 { 25 UpdateUI("100%", "后台任務完成!"); 26 } 27 //處理后台任務進度 28 void Value_Progress(BackgroundTaskRegistration sender, BackgroundTaskProgressEventArgs args) 29 { 30 var progress = args.Progress + "%"; 31 UpdateUI("后台任務進行中:", progress); 32 } 33 34 private async void registerButton_Click(object sender, RoutedEventArgs e) 35 { 36 TimeTrigger timetrigger = new TimeTrigger(30, false); 37 38 var SampleTask = new BackgroundTaskBuilder(); //創建后台任務實例 39 SampleTask.Name = "SimpleBackTask"; //指定后台任務名稱 40 SampleTask.TaskEntryPoint = "Basktask.SimpleTask";//指定后台任務名稱 41 SampleTask.SetTrigger(timetrigger);//指定后台任務的觸發器 42 43 SystemCondition internetCondition = new SystemCondition(SystemConditionType.InternetAvailable); 44 SampleTask.AddCondition(internetCondition); 45 46 var access = await BackgroundExecutionManager.RequestAccessAsync(); 47 if (access == BackgroundAccessStatus.AllowedMayUseActiveRealTimeConnectivity) 48 { 49 BackgroundTaskRegistration task = SampleTask.Register(); 50 task.Progress += Value_Progress; ; 51 task.Completed += Value_Completed; ; 52 UpdateUI("", "注冊成功"); 53 54 registerButton.IsEnabled = false; 55 cancelButtton.IsEnabled = true; 56 57 var settings = Windows.Storage.ApplicationData.Current.LocalSettings; 58 settings.Values.Remove(task.Name); 59 } 60 else if (access == BackgroundAccessStatus.Denied)//用戶禁用后台任務或后台任務數量已達最大 61 { 62 await new MessageDialog("您已禁用后台任務或后台任務數量已達最大!").ShowAsync(); 63 } 64 65 } 66 67 private void cancelButtton_Click(object sender, RoutedEventArgs e)//刪除后台任務 68 { 69 foreach (var task in BackgroundTaskRegistration.AllTasks) 70 { 71 if (task.Value.Name == "SimpleBackTask") 72 { 73 task.Value.Unregister(true);//刪除后台任務 74 } 75 } 76 registerButton.IsEnabled = true; 77 cancelButtton.IsEnabled = false; 78 UpdateUI("","后台任務取消"); 79 } 80 }
前台代碼:
1 <Grid> 2 <StackPanel HorizontalAlignment="Center"> 3 4 <Button Name="registerButton" 5 Content="注冊后台任務" 6 Click="registerButton_Click"></Button> 7 <Button Name="cancelButtton" 8 Content="取消后台任務" 9 Click="cancelButtton_Click"></Button> 10 <TextBlock Text=" 后台任務狀態" 11 FontSize="25"></TextBlock> 12 <TextBlock Name="statusText" 13 Text="未注冊" 14 FontSize="25"></TextBlock> 15 <TextBlock Text=" 后台任務進度" 16 FontSize="25"></TextBlock> 17 <TextBlock Text="未開始進行" 18 Name="progressText" 19 FontSize="25"> 20 21 </TextBlock> 22 23 </StackPanel> 24 </Grid>