zoukankan      html  css  js  c++  java
  • 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 {
    }

    声音播放代理:声音流可以存在独立存储内,机制与其他后台任务相同。

  • 相关阅读:
    【CV论文阅读】ExtremeC3Net: 使用高级C3模块的极轻量人像分割模型
    【pytorch基础】pytorch的初始化
    【CV基础】如何理解空洞卷积(dilated convolution)?
    关于研发规范化的一些实践和思考
    vuecli入门项目实战
    C/C++用.ico图片替换.exe图标(VS2017)(转)
    C# 多线程修改控件时,提示在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke(转)
    C#读取ACCESS提示“未在本地计算机上注册Microsoft.ACE.OLEDB.12.0提供程序
    ubuntu的常用命令
    C# DataTable 按整形字段排序
  • 原文地址:https://www.cnblogs.com/icuit/p/2815064.html
Copyright © 2011-2022 走看看