Готуємо Xamarin.Forms: налаштування оточення і перші кроки



Друзі! Ми продовжуємо колонку на тему розробки мобільних додатків на Xamarin. І
після невеликої перерви готові повернутися до розгляду особливостей використання Xamarin.Forms при розробці бізнес-додатків для iOS і Android. Всі статті з колонки можна буде знайти і прочитати за посиланням #xamarincolumn
У сьогоднішній статті ми розглянемо питання продуктивності додатків і оптимізації самого процесу розробки.

Правильні бджоли

У чудовій казці про Вінні-Пуха бджоли ділилися на правильних і неправильних. Аналогічно і оточення, в яких буде йти розробка додатків можуть бути умовно розділені на правильні і неправильні.

Почнемо ми з комп'ютерів, на яких буде йти розробка.

У своїй практиці як основний середовища ми використовуємо Windows 10 і Visual Studio 2015, тому зіткнулися з тим, що збірка додатків (у першу чергу Android) займає недозволено довго часу.

Ми стали з'ясовувати в чому тут справа і виявили кілька вузьких місць, що уповільнюють розробку:
  • під час складання Android-додатків Xamarin може в перший раз викачувати необхідні вихідні коди додаткових компонентів і складати їх на локальний диск для подальшого використання. Тут нічого вдіяти не можна, тому просто будьте готові до того, що перша збірка може зайняти у вас 10 хвилин.
  • далі починається найцікавіше: під час складання Xamarin гененерирует і використовує велику кількість файлів (до 200 МБ в папці bin obj, плюс ще ціла купа в папці Temp), тому одразу забудьте про використання жорстких дисків (HDD) на робочих станціях — чим швидше буде у вас SSD, тим краще.
Особливо просунутим можна рекомендувати використання ОЗУ в якості розділу для зберігання проектів і системної Temp папки — для цього потрібно використовувати одну з програм класу RAM Disk.Точних вимірювань при використанні SSD+RAM Disk не виробляли, але на око різниця колосальна.

Отже, вважаємо, що з правильним оточенням ми розібралися.

XAML — зло чи благо

Одним з важливих механізмів Xamarin.Forms є можливість використання XAML (на базі XML для опису інтерфейсу користувачів.

На наш погляд, це є хорошим рішенням з точки зору технології виробництва, так як відбувається відділення логіки від опису інтерфейсу і сама по собі UI-розробка стає дуже схожою на HTML-верстку, навіть стилі контролів можна задавати в одному місці як з CSS (лікнеп по стилям за адресою), включаючи невеликий тюнінг для різних платформ (Device.OnPlatform).

Все було б чудово, якби не одне велике «АЛЕ», яке характерне для Xamarin.Forms версії 1.х — XAML-файли інтерпретувалися на льоту, включаючи створення всіх необхідних контролів і їх розміщення на екрані. З-за цього кожне відкриття нового вікна зі складною компонуванням відбувалося довше, ніж хотілося б.

У версії 2.0 цей недолік усунули, реалізувавши попередню компіляцію XAML. Використовувати її можна як для окремих сторінок і View на XAML, так і для всього проекту цілком.

Включаємо компіляцію окремої XAML-сторінки (файл MainPage.xaml.cs, наприклад)

using Xamarin.Forms.Xaml;
...
[XamlCompilation (XamlCompilationOptions.Compile)]
public class MainPage : ContentPage
{ 
...
}


Активуємо компіляцію по всьому проекту — додаємо новий рядок в кінець файлу Properties/AssemblyInfo.cs PCL-проекті:

...
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]


Однак у деяких випадках, особливо при реалізації комірок для ListView, може бути ефективніше описати компонування для ViewCell/View/Page руками код на C# або спуститися на рівень iOS/Android.

Але до ListView ми ще повернемося.

Картинки, іконки і продуктивність

Перше, з чим стикаються початківці розробники на Xamarin.Forms — залипання при прокрутці в списках на базі ListView. Чого гріха таїти, це одне з болючих місць платформи, отбрасывающее тінь на весь функціонал, так як списки використовуються у великих кількостях і практично у всіх додатках.

Для початку ми розглянемо роботу з зображеннями, так як дуже часто це є однією з причин залипання.

Стандартний компонент для відображення Image хороший, навіть підтримує кешування, але він мало придатний при використанні в реальних проектах. Коли рік тому ми вперлися в обмеження Image, довелося зробити свій простенький кешер зображень з автоматичним масштабуванням — для відображення в клітинку передавалася зменшена версія, так як з великими зображеннями списки просто вмирали (це не проблема Xamarin.Forms, а взагалі будь-розробки додатків, але на Xamarin.Forms вона була дуже гострою).

Потім ми перепробували кілька різних бібліотек і врешті-решт зупинилися на чудовому компоненті під назвою FFImageLoading.



Він доступний в Nuget () і дозволяє вирішити відразу кілька завдань:
  • фонова завантаження зображень з можливістю повтору запитів;
  • використання placeholder під час завантаження;
  • автоматичне масштабування зображення до розмірів контрола, включаючи видалення Alpha-каналу на Android для ще більшої продуктивності;
  • можливість застосування трансформацій зображень після завантаження (обрізати до кола або іншої форми, накласти blur або іншою спец. ефект);
  • fade-анімація появи зображення після завантаження.
Ось так використовувати компонент при розробці на XAML:

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
x:Class="Sample.Pages.MainPage"
xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
Title="FFImageLoading Demo">
<ContentPage.Content>
<ffimageloading:CachedImage HorizontalOptions="Center" VerticalOptions="Center"
WidthRequest="300" HeightRequest="300"
DownsampleToViewSize="true"
Source = "https://unsplash.it/600/600/?random"
LoadingPlaceholder = "placeholder.png">
</ffimageloading:CachedImage>
</ContentPage.Content>
</ContentPage>

Ось так можна ще трохи поліпшити роботу FFImageLoading (клас AppDelegate.cs для iOS і MainActivity.cs для Android):

var config = new Configuration
{
HttpClient = new HttpClient(new ModernHttpClient.NativeMessageHandler()), //використовуємо швидкі бібліотеки для завантаження
FadeAnimationDuration = 250, //прискорюємо анімацію появи
};
FFImageLoading.ImageService.Instance.Initialize(config);

Працюємо зі списками в Xamarin.Forms

З допомогою FFImageLoading ми оптимізували відображення зображень у списках і тепер можемо перейти до наступного кроку.

Перша рекомендація стосується механізмів роботи ListView. У ранніх версіях Xamarin.Forms не підтримувався механізм повторного використання створених осередків, що призводило до створення примірників ViewCell кожен раз при необхідності їх відображення — це й було першою серйозною причиною залипання при скроле.

В останніх версіях Xamarin.Forms реалізований механізм повторного використання створених осередків і для його активації необхідно задати властивості CachingStrategy значення ListViewCachingStrategy.RecycleElement.

Реалізація в XAML:
<ListView CachingStrategy="RecycleElement">
...
</ListView>

Реалізація на C#:
var listView = new ListView(ListViewCachingStrategy.RecycleElement);


Після цього створені примірники ViewCell починають використовуватися повторно і до них просто підключаються (через Binding) необхідні моделі даних по мірі відображення.

Ще один цікавий спосіб підказав мій колега Кирило — просто зупиняти завантаження і відображення картинок під час прокручування списку. Цей спосіб також рекомендують використовувати і творці FFImageLoading.

Для цього необхідно зробити свій рендерер для ListView для кожної платформи і перевизначити події прокрутки.

Приклад для Android:
_listView.ScrollStateChanged += (object sender, ScrollStateChangedEventArgs scrollArgs) => {
switch (scrollArgs.ScrollState)
{
case ScrollState.Fling:
ImageService.Instance.SetPauseWork(true); // ставимо завантаження картинок на паузу 
break; 
case ScrollState.Idle: 
ImageService.Instance.SetPauseWork(false); // відновлюємо завантаження картинок 
// тут має бути ваш код відображення зображень відображаються в цих осередках 
ShowMyImage(); 
break;</p>
} 
}; 


При необхідності ви також можете створити свої реалізації ViewCell через механізм Custom Renderer для кожної платформи — такий підхід може бути актуальним для складних осередків з великою кількістю вбудованих контролів.

Також гарні результати при роботі з великими обсягами даних та складними осередками дозволяє досягти використання нативних компонентів UICollectionView (для iOS) і RecyclerView (для Android), але це рішення можна рекомендувати просунутим розробникам.

Приклад використання даних класів представлений в бібліотеці TwinTechs — обов'язково до знайомства, так як там є відео-ролики з результатами оптимізації.

Отже, на перших порах освоєння Xamarin.Forms необхідно приділити особливу увагу роботі зі списками і підходів до підвищення продуктивності. Це дозволить не відволікатися на дані особливості в подальшій розробці.

Висновок

В нашій сьогоднішній статті ми розглянули базові механізми оптимізації робочого оточення і перші кроки до розробки бізнес-додатків на базі Xamarin.Forms.

У наступному матеріалі ми розповімо про використання иконочных шрифтів в стилі Font Awesome, інструменту Fody для скорочення коду у ViewModel і механізми ручної відтворення своїх інтерфейсних елементів з допомогою бібліотеки NControlView.

Залишайтеся на зв'язку і додавайте свої коментарі та запитання!

Про авторів


В'ячеслав Черніков — керівник відділу розробки компанії Binwell. В минулому — один з Nokia Champion і Qt Certified Specialist, в даний час — спеціаліст по платформах Xamarin і Azure. У сферу mobile прийшов в 2005 році, з 2008 року займається розробкою мобільних додатків: починав з Symbian, Maemo, Meego, Windows Mobile, потім перейшов на iOS, Android і Windows Phone.

Корисні посилання

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.