Building High Performance and Reliable Windows Phone 8 Apps
-
Upload
michele-capra -
Category
Technology
-
view
1.033 -
download
2
description
Transcript of Building High Performance and Reliable Windows Phone 8 Apps
@piccoloaiutante - [email protected]
Michele CapraBuilding High Performance and Reliable Windows Phone 8 Apps
Tuesday, May 14, 13
Software contractor :
- C# Asp.net mvc, Wpf, Windows Phone..
- Python, Django
- WebDeBs Founder
@piccoloaiutante - OrangeCode Michele Capra
Who i am
Tuesday, May 14, 13
Building High Performance and Reliable Windows Phone 8 Apps
@piccoloaiutante - OrangeCode Michele Capra
What are we going to see
Tuesday, May 14, 13
Building High Performance and Reliable Windows Phone 8 Apps
@piccoloaiutante - OrangeCode Michele Capra
What are we going to see
Tuesday, May 14, 13
Building High Performance and Reliable Windows Phone 8 Apps
@piccoloaiutante - OrangeCode Michele Capra
What are we going to see
Tuesday, May 14, 13
In general, reliability (systemic def.) is the ability of a person or system to perform and maintain its functions in routine circumstances, as well as hostile or unexpected circumstances.
Wikipedia
@piccoloaiutante - OrangeCode Michele Capra
Reliability
Tuesday, May 14, 13
@piccoloaiutante - OrangeCode Michele Capra
Reliability
In general, reliability (systemic def.) is the ability of a person or system to perform and maintain its functions in routine circumstances, as well as hostile or unexpected circumstances.
Wikipedia
Tuesday, May 14, 13
How can we achieve reliability?
• Test your app
@piccoloaiutante - OrangeCode Michele Capra
Reliability
Tuesday, May 14, 13
Use automatic tests while you’re building your app.
Manually test your app at the end, especially when you’re integrating logic and UI.
@piccoloaiutante - OrangeCode Michele Capra
Testing
Tuesday, May 14, 13
Use automatic tests while you’re building your app.
Manually test your app at the end, especially when you’re integrating logic and UI.
@piccoloaiutante - OrangeCode Michele Capra
Testing
Tuesday, May 14, 13
Basic application:
- Query Spotify database
- Show result
@piccoloaiutante - OrangeCode Michele Capra
Sample App
Tuesday, May 14, 13
@piccoloaiutante - OrangeCode Michele Capra
Sample App
Tuesday, May 14, 13
@piccoloaiutante - OrangeCode Michele Capra
Sample App
http://ws.spotify.com/service/version/method[.format]?parameters
Tuesday, May 14, 13
Architectural Pattern:
• Derived from Presentation Model pattern (Fowler) • Clear separation between UI and Logic
Structure our code:
• ViewModel (c#): Logic• View (Xaml): Presentation
@piccoloaiutante - OrangeCode Michele Capra
Model-View-ViewModel in Windows Phone 8
Tuesday, May 14, 13
@piccoloaiutante - OrangeCode Michele Capra
Model-View-ViewModel in Windows Phone 8
ViewModel ViewProperty Binding
Tuesday, May 14, 13
We have to make a REST call to Spotify API.
We are going to create a service (a class called SongService) that could support our ViewModel in this action.
@piccoloaiutante - OrangeCode Michele Capra
Make a query to Spotify
Tuesday, May 14, 13
@piccoloaiutante - OrangeCode Michele Capra
Model-View-ViewModel in Windows Phone 8
ViewModelView SongService
Tuesday, May 14, 13
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28"> <TextBlock Text="OrangeCode" Margin="12,0"/> <TextBlock Text="Spotify Viewer" Margin="9,-‐7,0,0" /> </StackPanel> <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <Grid.RowDefinitions> <RowDefinition Height="80"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid > <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="150"/> </Grid.ColumnDefinitions> <TextBox Text="{Binding SearchedText,Mode=TwoWay}"/> <Button Content="search" Command="{Binding Search}"/> </Grid> <ScrollViewer Grid.Row="1"> <ItemsControl ItemsSource="{Binding TrackList}"> <ItemsControl.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding name}"/> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </ScrollViewer> </Grid>
@piccoloaiutante - OrangeCode Michele Capra
UI Language - Xaml
Tuesday, May 14, 13
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28"> <TextBlock Text="OrangeCode" Margin="12,0"/> <TextBlock Text="Spotify Viewer" Margin="9,-‐7,0,0" /> </StackPanel> <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <Grid.RowDefinitions> <RowDefinition Height="80"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid > <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="150"/> </Grid.ColumnDefinitions> <TextBox Text="{Binding SearchedText,Mode=TwoWay}"/> <Button Content="search" Command="{Binding Search}"/> </Grid> <ScrollViewer Grid.Row="1"> <ItemsControl ItemsSource="{Binding TrackList}"> <ItemsControl.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding name}"/> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </ScrollViewer> </Grid>
@piccoloaiutante - OrangeCode Michele Capra
UI Language - Xaml
Tuesday, May 14, 13
public class MainViewModel { private readonly ISongService _songService; public string SearchedText { get; set; }
public IList<track> TrackList { get; set; }
public MainViewModel(ISongService songService) { _songService = songService; TrackList= new List<track>(); }
public async Task Search() {
var data = await _songService.Query(SearchedText); TrackList = data.tracks; OnPropertyChanged("TrackList"); }
}
@piccoloaiutante - OrangeCode Michele Capra
Logic Language - C#
Tuesday, May 14, 13
public class MainViewModel { private readonly ISongService _songService; public string SearchedText { get; set; }
public IList<track> TrackList { get; set; }
public MainViewModel(ISongService songService) { _songService = songService; TrackList= new List<track>(); }
public async Task Search() {
var data = await _songService.Query(SearchedText); TrackList = data.tracks; OnPropertyChanged("TrackList"); }
}
@piccoloaiutante - OrangeCode Michele Capra
Logic Language - C#
Tuesday, May 14, 13
@piccoloaiutante - OrangeCode Michele Capra
Project Structure
Tuesday, May 14, 13
public class SongService : ISongService { string _baseUrl; private RestClient _client; public SongService() { _client = new RestClient(); _client.BaseUrl = "http://ws.spotify.com/search/1/track.json?q="; }
public Task<info> Query(string query) {
var request = new RestRequest(query, Method.GET);
var response= await _client.ExecuteTaskAsync<info>(request); return response.Data; } }
@piccoloaiutante - OrangeCode Michele Capra
SongService
Tuesday, May 14, 13
public class SongService : ISongService { string _baseUrl; private RestClient _client; public SongService() { _client = new RestClient(); _client.BaseUrl = "http://ws.spotify.com/search/1/track.json?q="; }
public Task<info> Query(string query) {
var request = new RestRequest(query, Method.GET);
var response= await _client.ExecuteTaskAsync<info>(request); return response.Data; } }
@piccoloaiutante - OrangeCode Michele Capra
SongService
Tuesday, May 14, 13
[TestClass] public class SongServiceFixture { private SongService _service; public SongServiceFixture() { _service = new SongService(); } [TestMethod] public async Task Query_Should_Return_Result_From_Spotify_Service() { var data = await _service.Query("Madonna"); Assert.IsTrue(data.tracks.Count!=0); } }
@piccoloaiutante - OrangeCode Michele Capra
SongService Test
Tuesday, May 14, 13
[TestClass] public class SongServiceFixture { private SongService _service; public SongServiceFixture() { _service = new SongService(); } [TestMethod] public async Task Query_Should_Return_Result_From_Spotify_Service() { var data = await _service.Query("Madonna"); Assert.IsTrue(data.tracks.Count!=0); } }
@piccoloaiutante - OrangeCode Michele Capra
SongService Test
Tuesday, May 14, 13
@piccoloaiutante - OrangeCode Michele Capra
MS Test Runner
Tuesday, May 14, 13
public class MainViewModel { private readonly ISongService _songService; public string SearchedText { get; set; } public IList<track> TrackList { get; set; }
public MainViewModel(ISongService songService) { _songService = songService; TrackList= new List<track>(); }
public async Task Search() { TrackList = (await _songService.Query(SearchedText)).tracks; } }
@piccoloaiutante - OrangeCode Michele Capra
ViewModel with service
Tuesday, May 14, 13
public class MainViewModel { private readonly ISongService _songService; public string SearchedText { get; set; } public IList<track> TrackList { get; set; }
public MainViewModel(ISongService songService) { _songService = songService; TrackList= new List<track>(); }
public async Task Search() { TrackList = (await _songService.Query(SearchedText)).tracks; } }
@piccoloaiutante - OrangeCode Michele Capra
ViewModel with service
Tuesday, May 14, 13
[TestMethod]
public void Search_Should_Get_Songs_From_Service() { var viewModel = new MainViewModel( new SongSearchService());
viewModel.SearchedText = "Madonna";
await viewModel.Search(); Assert.IsNotNull(viewModel.TrackList); Assert.IsTrue(viewModel.TrackList.Count >= 1); }
@piccoloaiutante - OrangeCode Michele Capra
Testing ViewModel with Service
Tuesday, May 14, 13
[TestMethod]
public void Search_Should_Get_Songs_From_Service() { var viewModel = new MainViewModel( new SongSearchService());
viewModel.SearchedText = "Madonna";
await viewModel.Search(); Assert.IsNotNull(viewModel.TrackList); Assert.IsTrue(viewModel.TrackList.Count >= 1); }
@piccoloaiutante - OrangeCode Michele Capra
Testing ViewModel with Service
Tuesday, May 14, 13
@piccoloaiutante - OrangeCode Michele Capra
MS Test Runner
Tuesday, May 14, 13
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28"> <TextBlock Text="OrangeCode" Margin="12,0"/> <TextBlock Text="Spotify Viewer" Margin="9,-‐7,0,0" /> </StackPanel> <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <Grid.RowDefinitions> <RowDefinition Height="80"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid > <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="150"/> </Grid.ColumnDefinitions> <TextBox Text="{Binding SearchedText,Mode=TwoWay}"/> <Button Content="search" Command="{Binding Search}"/> </Grid> <ScrollViewer Grid.Row="1"> <ItemsControl ItemsSource="{Binding TrackList}"> <ItemsControl.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding name}"/> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </ScrollViewer> </Grid>
@piccoloaiutante - OrangeCode Michele Capra
Manually test the UI
Tuesday, May 14, 13
Building High Performance and Reliable Windows Phone 8 Apps
@piccoloaiutante - OrangeCode Michele Capra
What are we going to see
Tuesday, May 14, 13
This subject involves different part of your application.
• App startup
• UI Thread
• Images
@piccoloaiutante - OrangeCode Michele Capra
Performance
Tuesday, May 14, 13
This subject involves different part of your application.
• App startup
• UI Thread
• Images
@piccoloaiutante - OrangeCode Michele Capra
Performance
Tuesday, May 14, 13
@piccoloaiutante - OrangeCode Michele Capra
Windows Phone 8 - Thread Architecture
UIThread
(touch,XAML,
draw visual,handler)
CompsitionThread
( feed GPU,texture,handle
transform)
GPU
YourApp
Tuesday, May 14, 13
@piccoloaiutante - OrangeCode Michele Capra
Windows Phone 8 - Thread Architecture
UIThread
(touch,XAML,
draw visual,handler)
CompsitionThread
( feed GPU,texture,handle
transform)
GPU
YourApp
Maintaining a lightweight UI thread is the key to writing a responsive app.
Tuesday, May 14, 13
UI thread: handles all input, which includes touching, parsing and creating objects from XAML, layout calculations, data binding, drawing all visuals (at least the first time they are drawn), rendering/rastering, process per-frame callbacks and executing other user code and event handlers.
@piccoloaiutante - OrangeCode Michele Capra
UI thread
Tuesday, May 14, 13
Composition/Render thread: feeds the GPU with textures and handles transform (scale, rotate, translate) animations and plane projections.
@piccoloaiutante - OrangeCode Michele Capra
Slice titile
Tuesday, May 14, 13
• Microsoft recommendation related to performance issues http://bit.ly/10yuFRw
• Performance best practice http://bit.ly/PiOzz9
@piccoloaiutante - OrangeCode Michele Capra
General Bottleneck
Tuesday, May 14, 13
How users perceive your app performance:
• Startup time
• Responsiveness
@piccoloaiutante - OrangeCode Michele Capra
Performance
Tuesday, May 14, 13
Visual Studio 2012 provides the Windows Phone Application Analysis tool.
Main feature:
• App Monitoring
• Profiling
@piccoloaiutante - OrangeCode Michele Capra
Performance tools
Tuesday, May 14, 13
App Monitoring: you can evaluate the most important behaviors of your app that contribute to a good user experience, such as start time and responsiveness.
@piccoloaiutante - OrangeCode Michele Capra
App monitoring
Tuesday, May 14, 13
Profiling: you can evaluate either execution-related or memory-usage aspects of your app.
@piccoloaiutante - OrangeCode Michele Capra
Profiling
Tuesday, May 14, 13
@piccoloaiutante - OrangeCode Michele Capra
App Analysis example App
Demo application with heavy jpg images
Tuesday, May 14, 13
@piccoloaiutante - OrangeCode Michele Capra
Performance tools
Tuesday, May 14, 13
@piccoloaiutante - OrangeCode Michele Capra
Performance tool session
Tuesday, May 14, 13
@piccoloaiutante - OrangeCode Michele Capra
Performance tool session
Tuesday, May 14, 13
@piccoloaiutante - OrangeCode Michele Capra
Performance tool session
Tuesday, May 14, 13
@piccoloaiutante - OrangeCode Michele Capra
Performance tool session
Tuesday, May 14, 13
Execution profiling graphs:
• External events• Frame rate• CPU usage %• Application responsiveness• Network data transfer MBps• Battery consumption mAh• Memory usage MB• Storyboards• Image loads• GC events
@piccoloaiutante - OrangeCode Michele Capra
Other session indicators
Memory profiling graphs:
• Memory usage MB• Image loads• GC events
Tuesday, May 14, 13
Visual Studio 2012 update 2, Windows Phone 8 SDK
Unit testing:• MS Test • Moq as mocking framework
Profiling:• Windows Phone Application Analysis tool
@piccoloaiutante - OrangeCode Michele Capra
Quick recap
Tuesday, May 14, 13
Email: [email protected]
Twitter: @piccoloaiutante
Blog: orangecode.it/blog
GitHub: github.com/piccoloaiutante
Linkedin:it.linkedin.com/in/michelecapra
@piccoloaiutante - OrangeCode Michele Capra
That’s all folks
Tuesday, May 14, 13