Upload
michele-capra
View
1.034
Download
2
Tags:
Embed Size (px)
DESCRIPTION
Have you ever dreamed to build a solid and fast application for your Windows Phone 8? Come to this session and you will see how to leverage the power of your device and how to deliver outstanding robust application. You'll discover how to unit test your WP8 application and how to tune its performance.
Citation preview
@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