07,Windows Phone后台代理


內容預告:

  • Windows Phone 任務管理
  • 用后台代碼實現多任務
  • 在Visual Studio中創建任務
  • 文件傳輸任務
  • 后台提醒
  • 后台音樂播放

前台任務:一般來說,一個Windows Phone應用程序運行在前台時,它可以與用戶直接交互,但同時只能有一個程序運行在前台,是為了保證性能和電量。

后台代理:Windows Phone應用程序可以開啟一個后台代理,類型可以是定期執行或資源密集型或兩者兼俱型,但每個程序只能有一個后台代理。后台代理和前台程序運行在后台不是一回事,后台代理只能做有限的事情。

后台代理的限制:在Windows Phone系統上同時可運行后台代理的數量有限的,且只有在條件允許的情況下操作系統才把CPU的控制權交給后台代理,省電模式下不能運行,用戶可以自己關閉。

代理和任務:一個任務是操作系統管理的在某個約定的時間執行的,有定期執行或資源密集型兩種。一個后台代理是真正要執行的代碼,代理代碼從BackgroundTask派生,是計划任務代理項目的一部分。

定期任務:大約每30分鍾執行一次,每次大約25秒,內存使用量小於6MB,兩次crash連續后會取消,同時活躍的任務數量有限制,適用於定位跟蹤,后台輪詢,磁貼更新。

資源密集型任務:外接電源時,電量大於90%,WiFi,鎖屏狀態,可連續運行10分鍾,內存使用量小於6MB,兩次crash連續后會取消,適合同步服務,解壓縮,壓縮數據庫。

兼俱型任務:可以用一個后台任務類運行兩種任務,系統會根據上下文判斷執行合適的任務。

后台代理功能:

定位跟蹤器:用后台代理以日志文件的方式存儲有規律地存儲手機的坐標,代理會在日志程序沒有焦點的時候更新位置數據。

創建后台代理:

連接代理項目:船長日志項目引用了一個定位任務項目的輸出,前台程序不直接引用任何代理類的對象或類。

后台代理代碼:必須實現OnInvode函數,它完成時會通知運行時系統。

namespace LocationLogTaskAgent
{
    public class ScheduledAgent : ScheduledTaskAgent
    {
        protected override void OnInvoke(ScheduledTask task)
        {
            //TODO: Add code to perform your task in background
            NotifyComplete();
        }
    }
}

 

與后台代理共享數據:通過獨立存儲

protected override void OnInvoke(ScheduledTask task)
{
    string message ="";
    string logString = "";
    if (LoadLogFromIsolatedStorageFile() {
        message = "Loaded";
    }
    else {
        message = "Initialised";
    }    ...
}

並發數據存儲:用互斥量(Mutex)保護存儲文件,保證釋放mutex。

public bool LoadLogFromIsolatedStorageFile()
{
    mut.WaitOne(); // Wait until it is safe to enter

    try  {          // read the file here
          return true;
    }
    catch { 
          LogText = ""; 
          return false;
    }
    finally {
        mut.ReleaseMutex(); // Release the Mutex. 
    }
}

鈎選定位能力:

獲取手機位置:通過GeoCoordinateWatcher類提供位置信息,在后台代理中使用Position,其每15分鍾更新一次。

protected override void OnInvoke(ScheduledTask task)
{
    ...
    GeoCoordinateWatcher watcher = new GeoCoordinateWatcher();
    watcher.Start();
    string positionString = watcher.Position.Location.ToString() + 
                            System.Environment.NewLine;
    ...
}

存儲手機位置:

protected override void OnInvoke(ScheduledTask task)
{
    ...
    logString = logString + timeStampString + " " + positionString;

    SaveLogToIsolatedStorageFile ();
    ...
}

顯示通知:后台任務可以彈出toast提醒,如果用戶點擊toast,可以啟動程序,Toast消息會在程序激活后消失。

protected override void OnInvoke(ScheduledTask task)
{
    ...
    logString = logString + timeStampString + " " + positionString;

    SaveLogToIsolatedStorageFile ();
    ...
}

安排一個后台代理:

PeriodicTask t;
t = ScheduledActionService.Find(taskName) as PeriodicTask;
bool found = (t != null);
if (!found)             
{
    t new PeriodicTask(taskName);
}
t.Description = description;
t.ExpirationTime = DateTime.Now.AddDays(10);
if (!found)
{
    ScheduledActionService.Add(t);
}             
else
{
    ScheduledActionService.Remove(taskName);
    ScheduledActionService.Add(t);
}

調試后台任務:我們可以強制服務啟動代理,因為30分鍾才能執行一次太煩人了。

#if DEBUG_AGENT
 ScheduledActionService.LaunchForTest(taskName, TimeSpan.FromSeconds(60));
#endif

Tips:

  • 經常續訂,因為后台任務只能持續2周有效。
  • 不實現后台代理的臨界功能,因為用戶可能禁用,系統也可能因為電量原理掛起程序。
  • 如果需要穩定的更新磁貼或Toast消息,考慮用推送。

文件傳輸任務:程序不運行也可以傳輸,可以監視下載狀態,支持HTTP、HTTPS,但不支持FTP。

傳輸限制:上傳最大5MB,通過手機網絡下載最大20MB,通過WiFi最大100MB,這些數字可以通過修改TransferPreferences的值。每個程序最多可以請求25次。

后台傳輸命名空間:using Microsoft.Phone.BackgroundTransfer;

創建一個后台傳輸:POST用來發送文件到服務器。

Uri transferUri = new Uri(Uri.EscapeUriString(transferFileName), UriKind.RelativeOrAbsolute);
// Create the new transfer request, passing in the URI of the file to 
// be transferred.
transferRequest = new BackgroundTransferRequest(transferUri);

// Set the transfer method. GET and POST are supported.
transferRequest.Method = "GET";

設置傳輸目標:

string downloadFile = transferFileName.Substring(transferFileName.LastIndexOf("/") + 1);
// Build the URI
downloadUri = new Uri("shared/transfers/" + downloadFile, UriKind.RelativeOrAbsolute);
transferRequest.DownloadLocation = downloadUri;

// Set transfer options
transferRequest.TransferPreferences = TransferPreferences.AllowCellularAndBattery;

開始傳輸:

try {
    BackgroundTransferService.Add(transferRequest);
}
catch (InvalidOperationException ex) {
    MessageBox.Show("Unable to add background transfer request. " 
                                                             + ex.Message);
}
catch (Exception) {
    MessageBox.Show("Unable to add background transfer request.");
}

監視傳輸:TransferProcessChanged是為進度條准備的,TransferStatusChanged在完成或失敗時觸發。

// Bind event handlers to the progess and status changed events
transferRequest.TransferProgressChanged += 
    new EventHandler<BackgroundTransferEventArgs>(
        request_TransferProgressChanged);

transferRequest.TransferStatusChanged += 
    new EventHandler<BackgroundTransferEventArgs>(
        request_TransferStatusChanged);
void request_TransferProgressChanged(object sender, 
                                     BackgroundTransferEventArgs e)
{
    statusTextBlock.Text = e.Request.BytesReceived + " received.";
}
void request_TransferStatusChanged(object sender, BackgroundTransferEventArgs e) {
  switch (e.Request.TransferStatus) {
     case TransferStatus.Completed:
         // If the status code of a completed transfer is 200 or 206, the
         // transfer was successful
         if (transferRequest.StatusCode == 200 ||transferRequest.StatusCode == 206)
         {
            // File has arrived OK – use it in the program
         }

移除一個傳輸:

try {
    BackgroundTransferService.Remove(transferRequest);
}
catch {
}

聲音播放代理:聲音流可以存在獨立存儲內,機制與其他后台任務相同。

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM