Windows Phone 8 後臺代理(P1:週期性任務)

引言:

當Windows Phone應用程序不在前臺運行的時候,抑或者應用程序在休眠狀態下或者設備鎖住的時候,計劃任務和後臺代理則可以運行在後臺,幫助應用程序來處理一些簡單的事務,今天開始,我將梳理自己所掌握的Windows Phone知識並結合內部資料,爭取更深的吃透Windows Phone平臺的運行機制.以此勉之!(PS: 不會按任何順序講述,需要讀者具備並瞭解XAML的數據綁定、MVVM設計模式以及其他相關的知識)。

後臺代理介紹

1、後臺代理的類型

  • 週期性的任務,即:Periodic Task
  • 資源密集性的任務,即: Resource Intensive Task.

2、當創建後臺代理時,你需要了解..

  • 一個應用程序僅能運行一個後臺代理, 它可以是週期性的,也可以是資源密集性的,也可以是兩者共存。
  • 任務計劃的運行,取決於你事先註冊 了哪種類型的代理任務。
  • 在後臺代理中,不要把業務的關鍵邏輯寫進去,否則,你將會像調進泥潭一樣不能自拔,當初我們寫雲城客戶端時就碰到了類似的錯誤。

3、應該考慮哪些計劃任務的約束條件?

  • 3.1、不支持的APIs
    • 有些API在計劃任務中是不被支持的.
  • 3.2、內存使用的限制
    • 只有11MB內存可供利用
    • 音頻類代理能夠使用到15MB內存。
  • 3.3、每兩週可以改變計劃任務的需求設定
    • 如果想讓某個計劃任務不再運行,可以設置該任務的過期時間屬性對象。
    • 過期時間屬性的值至少要2周。
    • 如果後臺代理任務被用於更新動態瓷貼,那麼過期時間自動順延2周時間。
    • 如果需要在鎖屏界面中顯示通知,當你再次調用後臺代理時,過期時間同樣也會順延2周時間.
    • 假設你的應用有照片上傳的功能,使用了資源密集型任務,這可能要求一直保持該任務運行,此時,你需要到 照片+相機 的設置頁中開啓.
  • 3.4、如果應用程序有兩次不定期的崩潰,那麼,後臺代理任務的執行會變得混亂,不按原來的計劃執行。

以上是在使用後臺代理時應用注意的一些事項,各位在開發過程中,一定要注意這些,尤其是內存及時間的要求,接下來,我們來詳細看看週期性代理的實現原理及注意事項:

4、週期性代理

在我們正式開始編寫週期性代理任務之前,先來了解下週期代理的一些約束條件及注意事項,以便我們能夠更好的掌握、利用其特性。

  • 4.1、計劃任務執行的間隔:通常是30分鐘執行一次。
  • 4.2、計劃任務的連續性:每25秒運行。
  • 4.3、如果開啓電源節約模式,週期性代理將不會運行。
  • 4.4、在每臺設備中,只允許運行6個週期性代理。

5、代碼實戰

  • 使用VS2013 RC創建簡單的後臺代理項目,如圖:

001

  • 添加主要命名空間
     using Microsoft.Phone.Shell;
  • 在OnInvoke()方法中實現代理功能,本例子主要通過後臺代理,將消息通知到前臺,實現過程如下:
      protected override void OnInvoke(ScheduledTask task)
        {
            //TODO: Add code to perform your task in background
            string ToastMessage = string.Empty;
            if (task is PeriodicTask)
            {
                ToastMessage = string.Format("週期性任務正在運行...");
            }
            var toast = new ShellToast();
            toast.Title = "後臺代理實戰!";
            toast.Content = ToastMessage;
            toast.Show();
            NotifyComplete();
            #if DEBUG_AGENT //在調試模式下設定代理的運行時間間隔,如果不寫這段代理,那就只能等待....
            ScheduledActionService.LaunchForTest(task.Name,TimeSpan.FromSeconds(60));
            #endif
        }
  • 實現MainPage.xaml頁面的UI佈局.

003

  • 在項目中創建:ViewModel文件夾,創建名稱爲:PeriodicTaskConfigure.cs的週期代理任務配置。
#define DEBUG_AGENT
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Phone.Scheduler;

namespace PhoneApp1.ViewModel
{
    public class PeriodicTaskConfigure : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }

        PeriodicTask periodicTask { get; set; }
        public string Name = "週期性代理";
        private bool? _isEnabled;
        public bool? IsEnabled
        {
            get { return _isEnabled; }
            set
            {
                _isEnabled = value;
                OnPropertyChanged("IsEnabled");
            }
        }
        private bool? _isScheduled;
        public bool? IsScheduled
        {
            get { return _isScheduled; }
            set
            {
                _isScheduled = value;
                OnPropertyChanged("IsScheduled");
            }
        }
        private DateTime? _lastScheduledTime;
        public DateTime? LastScheduledTime
        {
            get { return _lastScheduledTime; }
            set
            {
                _lastScheduledTime = value;
                OnPropertyChanged("LastScheduledTime");
            }
        }
        private DateTime? _expirationTime;
        public DateTime? ExpirationTime
        {
            get { return _expirationTime; }
            set
            {
                _expirationTime = value;
                OnPropertyChanged("ExpirationTime");
            }
        }

        private string _LastExitReason;
        public string LastExitReason
        {
            get { return _LastExitReason; }
            set
            {
                _LastExitReason = value;
                OnPropertyChanged("LastExitReason");
            }
        }
       public void Page_Active()
        {
            periodicTask = ScheduledActionService.Find(Name) as PeriodicTask;

            if (periodicTask != null)
            {
            }
        }
        public void StartPeriodicAgent()
        {
            periodicTask = ScheduledActionService.Find(Name) as PeriodicTask;
            if (periodicTask != null)
            {
                RemoveAgent();
            }
            periodicTask = new PeriodicTask(Name);
            periodicTask.Description = "這裏描述週期性代理的用途.";

            try
            {
                ScheduledActionService.Add(periodicTask);
                LoadPeriodicTaskData();

#if(DEBUG_AGENT)
                ScheduledActionService.LaunchForTest(Name, TimeSpan.FromSeconds(60));
#endif
            }
            catch (Exception e) { }
        }

        public void RemoveAgent()
        {
            try
            {
                ScheduledActionService.Remove(Name);
                EmptyPeriodicData();
            }
            catch (Exception e)
            { }
        }
        private void LoadPeriodicTaskData()
        {
            this.IsEnabled = periodicTask.IsEnabled;
            this.IsScheduled = periodicTask.IsScheduled;
            this.LastScheduledTime = periodicTask.LastScheduledTime;
            this.LastExitReason = periodicTask.LastExitReason.ToString();
            this.ExpirationTime = periodicTask.ExpirationTime;
        }
        private void EmptyPeriodicData()
        {
            this.IsEnabled = null;
            this.IsScheduled = null;
            this.LastScheduledTime = null;
            this.LastExitReason = null; ;
            this.ExpirationTime = null;
        }
    }
}
  • 在App.xaml.cs中聲明 PeriodicTaskConfigure屬性,在App()構造函數中實現該類的一個對象。
    private static PeriodicTaskConfigure _periodicTaskConfigure;
    public static PeriodicTaskConfigure periodicTaskConfigure
        {
            get { return _periodicTaskConfigure; }
        }
  • 在MainPage.xaml.cs中,將DataContext設置爲PeriodicTaskConfigure的實現。
       public MainPage()
        {
            InitializeComponent();
            this.DataContext = App.periodicTaskConfigure;
            // Sample code to localize the ApplicationBar
            //BuildLocalizedApplicationBar();
        }
  • 經過如上設置,我們就可以在MainPage.xaml中去調用PeriodicTaskConfigure對象中的實現方法。
          private void PeriodicCheckBox_Checked(object sender, RoutedEventArgs e)
            {
                App.periodicTaskConfigure.StartPeriodicAgent();
            }
            private void PeriodicCheckBox_Unchecked(object sender, RoutedEventArgs e)
            {
                App.periodicTaskConfigure.RemoveAgent();
            }
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
                App.periodicTaskConfigure.Page_Active();
            }

最終的實現效果是這個樣子地:

a b

你的運行效果是這樣的麼?如果不是,彆着急,這裏有: Windows Phone 8 後臺代理 (P1:週期性代理) 源碼

如果有任何問題,請到 http://ask.metrofeng.com 提問,24小時在線解答。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章