Hallo allemaal,
Op dit moment ben ik de laatste hand aan het leggen op versie 4.0 van Regenmeter. Deze versie is gemaakt a.h.v. het universele app model in WinRT (gebruikmakend van C# en XAML).
De laatste stap is het genereren van de live tiles in de BackgroundTask. Ik gebruik hiervoor de XamlRenderingBackgroundTask, en dat gaat in principe goed in Debug mode. Bij het uploaden naar de Store gaat het echter mis: BTs mogen daar maar minder MB aan geheugen verbruiken (rond de 20). Ik ga daar overheen met 3 a 4 MB. De achtergrondtaak doet het volgende:
De 4 'render functies' maken gebruik van de data die is opgehaald, en gebruiken dat als input om de tiles te generen. Ik heb dus 4 functies (voor elke tile 1). Zo'n functie ziet er zo uit:
Op MSDN wordt geadviseerd om gebruik te maken van C++ i.p.v. C# om het geheugen niet te veel te belasten. Ik heb echter weinig kaas gegeten van C++, en dat zou dan voor mijn hele BT gelden
.
Ik had een ander idee om de bovenstaande Render functie naar C++ te herschrijven, en dat als los runtime component in mijn project te stoppen.
Je kan dan in de C# achtergrondtaak de data ophalen, die doorsturen naar het C++ object, die rendert alles en stuurt dan een URL terug. De vraag is of dat uberhaupt kan en gaat.. en hoe?
Misschien hebben jullie nog goede ideeen om het geheugen gebruik te limieteren.
Groeten,
Niels
Op dit moment ben ik de laatste hand aan het leggen op versie 4.0 van Regenmeter. Deze versie is gemaakt a.h.v. het universele app model in WinRT (gebruikmakend van C# en XAML).
De laatste stap is het genereren van de live tiles in de BackgroundTask. Ik gebruik hiervoor de XamlRenderingBackgroundTask, en dat gaat in principe goed in Debug mode. Bij het uploaden naar de Store gaat het echter mis: BTs mogen daar maar minder MB aan geheugen verbruiken (rond de 20). Ik ga daar overheen met 3 a 4 MB. De achtergrondtaak doet het volgende:
- Geolocaten van device.
- Ophalen van relevante weer informatie.
- Locatienaam ophalen via Bing.
- A.d.v. die data 4 tiles genereren (MediumFront, MediumBack, WideFront, WideBack.
C#:
1
2
3
4
5
6
7
| //// Data is opgehaald, tiles worden aangemaakt. string WideFrontTile = await RenderWideFront(WeatherData, bingResult.CityName); string MediumFrontTile = await RenderMediumFront(WeatherData, bingResult.CityName); string WideBackTile = await RenderWideBack(WeatherData); string MediumBackTile = await RenderMediumBack(WeatherData); //// Alle URLs worden gepushed naar de live tiles. |
De 4 'render functies' maken gebruik van de data die is opgehaald, en gebruiken dat als input om de tiles te generen. Ik heb dus 4 functies (voor elke tile 1). Zo'n functie ziet er zo uit:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
| private async Task<string> RenderMediumFront(WorldWeatherOnline.WeatherClass weatherClass, string Location) { var folder = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync("Assets"); var file = await folder.GetFileAsync("MediumFrontTile.xml"); string szCustomTileXML = await Windows.Storage.FileIO.ReadTextAsync(file); Border tile = XamlReader.Load(szCustomTileXML) as Border; string TileURI = "MediumFront.png"; if (null != tile) { Grid grid = tile.Child as Grid; TextBlock tempTxt = grid.FindName("tempTxt") as TextBlock; tempTxt.Text = weatherClass.Temp; TextBlock conditionTxt = grid.FindName("conditionTxt") as TextBlock; conditionTxt.Text = weatherClass.Condition.ToUpper(); Path iconPath = grid.FindName("iconPath") as Path; iconPath.Data = supportingClasses.PathMarkupToGeometry(weatherClass.IconPath); TextBlock locationTxt = grid.FindName("locationTxt") as TextBlock; locationTxt.Text = Location; RenderTargetBitmap rtb = new RenderTargetBitmap(); await rtb.RenderAsync(tile, 336, 336); IBuffer pixels = await rtb.GetPixelsAsync(); DataReader dReader = Windows.Storage.Streams.DataReader.FromBuffer(pixels); byte[] data = new byte[pixels.Length]; dReader.ReadBytes(data); var outputFile = await Windows.ApplicationModel.Package.Current.InstalledLocation.CreateFileAsync(TileURI, Windows.Storage.CreationCollisionOption.ReplaceExisting); var outputStream = await outputFile.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite); BitmapEncoder enc = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, outputStream); enc.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied, (uint)rtb.PixelWidth, (uint)rtb.PixelHeight, 96, 96, data); await enc.FlushAsync(); } return TileURI; } |
Op MSDN wordt geadviseerd om gebruik te maken van C++ i.p.v. C# om het geheugen niet te veel te belasten. Ik heb echter weinig kaas gegeten van C++, en dat zou dan voor mijn hele BT gelden
Ik had een ander idee om de bovenstaande Render functie naar C++ te herschrijven, en dat als los runtime component in mijn project te stoppen.
Je kan dan in de C# achtergrondtaak de data ophalen, die doorsturen naar het C++ object, die rendert alles en stuurt dan een URL terug. De vraag is of dat uberhaupt kan en gaat.. en hoe?
Misschien hebben jullie nog goede ideeen om het geheugen gebruik te limieteren.
Groeten,
Niels
Trein & Regenmeter voor Windows Phone 7.x & 8!