Обновление активной плитки при выходе из приложения - любые ограничения / лучшие практики - PullRequest
0 голосов
/ 08 марта 2012

У меня есть приложение, в котором я хотел бы обновить живую плитку, когда пользователь покидает приложение. Первый вопрос: если это плохая идея? Если пользователь запускает приложение 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 ]

1 голос
/ 04 мая 2012

Есть способ избежать ваших проблем.

Пользователь закрывает приложение с помощью кнопки "назад", верно?Таким образом, вы можете воспользоваться этим.

Просто добавьте метод к этому событию, оно должно быть выполнено полностью, прежде чем приложение будет закрыто.В вашем методе MainPage () введите:

this.BackKeyPress += new EventHandler<System.ComponentModel.CancelEventArgs>((sender, e) =>
{
    blablablablabla - your code;
});
0 голосов
/ 08 марта 2012

Как правило, делать вещи при выходе из приложения - плохая идея. Разве вы не можете найти другую точку (или точки) в рамках общей операции приложения, чтобы вместо этого было выполнено это действие?

Вы не сказали, как обновляете плитку обратно, но если вы загружаете изображения самостоятельно, очень похоже, что вы не сможете сделать это при выходе из приложения. Также асинхронный запрос на получение изображения не будет блокировать закрытие приложения, пока вы ожидаете ответа, поэтому вполне вероятно, что запрос будет просто отменен. Попытка заблокировать закрытие приложения во время ожидания ответа будет очень плохой идеей, и если это займет более пары секунд, это может привести к тому, что процесс вашего приложения будет убит ОС.

0 голосов
/ 16 марта 2012

Попробуйте обновить плитку при запуске приложения.

Если вы обновите его в Application_Activation, при быстром переключении между меню «Пуск» и главной панорамой должен быть черный экран. Это не работает, чтобы обновить его в Application_Closing / Application_Deactivation либо

0 голосов
/ 08 марта 2012

Нет точных указаний относительно того, сколько именно времени вам придется завершать обработку, когда ваше приложение деактивировано.Если вы посмотрите на раздел 5.2 Требования к технической сертификации , он дает несколько сценариев, касающихся сроков реагирования при выходе / перезапуске приложения (необходимо запустить в течение 5 секунд, его можно использовать в течение 20секунд).Несоблюдение этих требований может помешать сертификации вашего приложения.Существует также сторожевой процесс, который прервет ваш код, если он не будет закрыт в течение определенного периода времени (извините, не могу найти здесь точные цифры).Это можно увидеть в действии, если вы намеренно поместили долгосрочное задание - или даже Thread.Sleep() - в конструктор стартовой страницы.

Если вы создаете образ локально (т. Е. Нет сетевых вызовов)тогда, если это не сложное изображение, у вас должно быть достаточно времени, чтобы сделать то, что вы ищете.У меня есть подобное требование в моем приложении, но для получения изображения требуется сетевой вызов.В результате я запускаю задачу обновления при запуске приложения, поэтому, пока приложение загружается, я могу начать извлекать изображение и молча обновлять его, пока пользователь отвлекается на мое приложение.

Что касается вашего изображения, заканчивающегося чернымесли вы выходите немедленно - это пока ваш заставка все еще отображается?Я считаю, что если конструктор вашей первой страницы еще не отображается, сторожевой таймер будет вести себя немного иначе.

...