本文共 5343 字,大约阅读时间需要 17 分钟。
内容预告:
前台任务:一般来说,一个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:
文件传输任务:程序不运行也可以传输,可以监视下载状态,支持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 URIdownloadUri = new Uri("shared/transfers/" + downloadFile, UriKind.RelativeOrAbsolute);transferRequest.DownloadLocation = downloadUri;// Set transfer optionstransferRequest.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 eventstransferRequest.TransferProgressChanged += new EventHandler( request_TransferProgressChanged);transferRequest.TransferStatusChanged += new EventHandler ( 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 {}
声音播放代理:声音流可以存在独立存储内,机制与其他后台任务相同。
转载地址:http://dllgb.baihongyu.com/