退出应用时更新实时磁贴 - 任何限制/最佳实践

时间:2012-03-08 09:38:36

标签: windows-phone-7 live-tile

我有一个应用,我希望在用户离开应用时更新实时磁贴。第一个问题是,这是一个坏主意吗?如果用户每天启动应用程序20次,这是一个坏主意或以任何方式影响后台服务?

第二个问题是,这可能存在多长时间或资源密集程度。我想我会把这个代码放在OnNavigatedFrom中,如果活动磁贴的更新花费太长时间操作系统是否会杀死应用程序?我需要创建一个图像,将其保存到隔离存储,读取图像然后更新图块。

真的很期待你的一些想法。

编辑1:我问的原因是,如果我像上面那样做,它就可以了。但是如果我在启动时立即退出应用程序,我只会得到一个黑色的瓷砖而不是带有背景图像的瓷砖。所以我觉得代码没有完成。我怎么能避免这种情况?

编辑2:由于我正在动态创建实时图块,我认为问题是加载背景图像。我加载背景图像,然后添加文本。当瓷砖变黑时,我仍然可以看到文字,因此必须加载用作瓷砖背景的背景图像。

编辑3:这是用于创建用作背景图像的图像的完整代码。我试着简化它以减少代码。

Grid grid = new Grid();

StackPanel sp = new StackPanel();
sp.Height = 173;
sp.Width = 173;

sp.Background = (SolidColorBrush)Application.Current.Resources["PhoneAccentBrush"];
strBackBackground = "";

StreamResourceInfo info;

sp.Background = (SolidColorBrush)Application.Current.Resources["PhoneAccentBrush"];
strBackBackground = "";
info = Application.GetResourceStream(new Uri("/MyApp;component/images/Icons/livetile/metro-" + strSymbol + ".png", UriKind.Relative));

// create source bitmap for Image control (image is assumed to be alread 173x173)
WriteableBitmap wbmp3 = new WriteableBitmap(1, 1);
try
{
    wbmp3.SetSource(info.Stream);
}
catch
{
}

Image img3 = new Image();
img3.Source = wbmp3;
// add Image to Grid
img3.Width = 173;
img3.Height = 173;
img3.Margin = new Thickness { Left = 0, Bottom = 0, Right = 0, Top = 0 };

TextBlock txtTemperature = new TextBlock();
TextBlock txtTemperatureRing = new TextBlock();

txtTemperature.Foreground = new SolidColorBrush(Colors.White);
txtTemperature.Text = strTemp;
txtTemperature.TextAlignment = TextAlignment.Right;
txtTemperatureRing.Style = (Style)Application.Current.Resources["PhoneTextTitle3Style"];
txtTemperatureRing.FontFamily = new FontFamily("Segoe WP Light");
txtTemperatureRing.FontSize = 40;
txtTemperatureRing.Foreground = new SolidColorBrush(Colors.White);
txtTemperatureRing.Text = "°";
txtTemperatureRing.TextAlignment = TextAlignment.Right;

txtTemperature.FontFamily = new FontFamily("Segoe WP");
txtTemperature.FontSize = 40;
txtTemperature.Margin = new Thickness { Left = 0, Bottom = 0, Right = 0, Top = -55 };
txtTemperature.Height = 80;
txtTemperature.Width = 135;
txtTemperatureRing.Margin = new Thickness { Left = 130, Bottom = 0, Right = 0, Top = -112 };
txtTemperatureRing.Height = 50;
txtTemperatureRing.Width = 29;

sp.Children.Add(img3);
sp.Children.Add(txtTemperature);
sp.Children.Add(txtTemperatureRing);

//call measure, arrange and updatelayout to prepare for rendering
sp.Measure(new Size(173, 173));
sp.Arrange(new Rect(0, 0, 173, 173));
sp.UpdateLayout();
grid.Children.Add(sp);

WriteableBitmap wbmp = new WriteableBitmap(173, 173);
wbmp.Render(grid, null);
wbmp.Invalidate();

//write image to isolated storage
string sIsoStorePath = @"\Shared\ShellContent\tile.png";
using (IsolatedStorageFile appStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
    //ensure directory exists
    String sDirectory = System.IO.Path.GetDirectoryName(sIsoStorePath);
    if (!appStorage.DirectoryExists(sDirectory))
    {
        appStorage.CreateDirectory(sDirectory);
    }

    using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(sIsoStorePath, System.IO.FileMode.Create, appStorage))
    {
        wbmp.SaveJpeg(stream, 173, 173, 0, 100);
    }
}


/// If application uses both PeriodicTask and ResourceIntensiveTask
if (task is PeriodicTask)
{

    ShellTile TileToFind = ShellTile.ActiveTiles.First();


    if (TileToFind != null)
    {
        StandardTileData NewTileData = new StandardTileData
        {
            BackgroundImage = new Uri("isostore:Shared/ShellContent/tile.png", UriKind.Absolute),
            Title = strTitle,
            Count = null,
            BackTitle = (string)settings["SelectedCityName"],
            BackBackgroundImage = new Uri(strBackBackground, UriKind.Relative),
            BackContent = strWind + Environment.NewLine + strPrecipitation
        };

        TileToFind.Update(NewTileData);
    }
}

4 个答案:

答案 0 :(得分:1)

有一种方法可以避免你的问题。

用户正在使用“后退”按钮关闭应用程序,对吗?所以你可以冒险尝试。

只需在此事件中添加方法,就必须在应用关闭之前完全执行。在MainPage()方法中键入:

this.BackKeyPress += new EventHandler<System.ComponentModel.CancelEventArgs>((sender, e) =>
{
    blablablablabla - your code;
});

答案 1 :(得分:0)

在您的应用程序停用时,您必须完成处理的确切时间没有硬指南。如果您查看Technical Certification Requirements 5.2 部分,它会在退出/重新启动您的应用程序时提供一些响应时间限制的方案(必须在5秒内启动,在20秒内可用)。不遵守这些要求可能会妨碍您的申请获得认证。还有一个监视程序,如果它在一段时间内没有关闭,将终止你的代码(抱歉,无法在这里找到确切的数字)。如果您故意在启动页面的构造函数中放置一个运行时间很长的任务 - 甚至是Thread.Sleep(),那么您可以看到这一点。

如果您在本地创建图片(即没有网络电话),那么除非它是一张复杂的图片,否则您应该有足够的时间来完成您之后的工作。我在我的应用程序中有类似的要求,但它需要网络调用来获取图像。因此,我在应用程序启动时启动了更新任务,因此在应用程序加载时,我可以开始获取图像并在用户被我的应用程序分心时静默更新它。

如果您立即退出,您的图片会以黑色结束 - 这是在您的启动画面仍然显示的情况下吗?我相信如果您的第一页构造函数尚未显示,那么看门狗的行为会略有不同。

答案 2 :(得分:0)

作为一般规则,退出应用程序时做事是个坏主意。您是否可以在应用程序的一般操作中找到另一个或多个点来代替这个问题?

您还没有说过如何更新磁贴,但如果您自己下载图像,则很可能在退出应用时无法执行此操作。此外,在您等待响应时,获取图像的异步请求不会阻止关闭应用程序,因此请求可能会被中止。在等待响应时试图阻止关闭应用程序将是一个非常糟糕的主意,如果花费超过几秒钟,则会导致您的应用程序进程被操作系统杀死。

答案 3 :(得分:0)

尝试在Application_Launching更新磁贴。

如果您在Application_Activated更新它,在开始菜单和主全景之间快速切换时必须有黑屏。它无法在Application_Closing / Application_Deactivated

中更新它