Výkon Xamarin. AndroidXamarin.Android Performance

Existuje mnoho způsobů, jak zvýšit výkon aplikací vytvořených pomocí Xamarin. Android. Souhrnně tyto techniky můžou významně snížit množství práce prováděné CPU a množství paměti, které aplikace spotřebovává. Tento článek popisuje a popisuje tyto techniky.There are many techniques for increasing the performance of applications built with Xamarin.Android. Collectively these techniques can greatly reduce the amount of work being performed by a CPU, and the amount of memory consumed by an application. This article describes and discusses these techniques.

Přehled výkonuPerformance Overview

Nízký výkon aplikace prezentuje mnoho způsobů.Poor application performance presents itself in many ways. Může dojít k tomu, že aplikace přestane reagovat, může způsobit pomalé posouvání a může snížit výdrž baterie.It can make an application seem unresponsive, can cause slow scrolling, and can reduce battery life. Optimalizace výkonu však zahrnuje více než pouze implementaci efektivního kódu.However, optimizing performance involves more than just implementing efficient code. Také je nutné vzít v úvahu činnost uživatele při výkonu aplikace.The user's experience of application performance must also be considered. Například zajistěte, aby se operace prováděly bez blokování uživatele, aby mohli provádět další aktivity, což může pomoci zlepšit uživatelské prostředí.For example, ensuring that operations execute without blocking the user from performing other activities can help to improve the user's experience.

Existuje několik postupů pro zvýšení výkonu a zjištěného výkonu aplikací vytvořených pomocí Xamarin. Android.There are a number of techniques for increasing the performance, and perceived performance, of applications built with Xamarin.Android. Mezi ně patří:They include:

Poznámka

Než si přečtete tento článek, měli byste nejdřív přečíst výkon pro různé platformy, který popisuje techniky specifické pro jiné platformy, aby se zlepšilo využití paměti a výkon aplikací vytvořených pomocí platformy Xamarin.Before reading this article you should first read Cross-Platform Performance, which discusses non-platform specific techniques to improve the memory usage and performance of applications built using the Xamarin platform.

Optimalizace hierarchií rozloženíOptimize Layout Hierarchies

Každé rozložení přidané do aplikace vyžaduje inicializaci, rozložení a vykreslení.Each layout added to an application requires initialization, layout, and drawing. Úspěšnost rozložení může být nákladné při vnořování LinearLayout instancí, které používají weight parametr, protože každá podřízená položka bude změřena dvakrát.The layout pass can be expensive when nesting LinearLayout instances that use the weight parameter, because each child will be measured twice. Použití vnořených instancí LinearLayout může vést k hierarchii hloubkového zobrazení, což může vést k nedostatečnému výkonu pro rozložení, která jsou rozčleněná několikrát, například v ListView .Using nested instances of LinearLayout can lead to a deep view hierarchy, which can result in poor performance for layouts that are inflated multiple times, such as in a ListView. Proto je důležité, aby taková rozložení byla optimalizována, protože výhody výkonu budou vynásobeny.Therefore, it's important that such layouts are optimized, as the performance benefits will then be multiplied.

Zvažte například LinearLayout řádek pro zobrazení seznamu, který má ikonu, název a popis.For example, consider the LinearLayout for a list view row that has an icon, a title, and a description. LinearLayoutBude obsahovat ImageView a svislou LinearLayout , která obsahuje dvě TextView instance:The LinearLayout will contain an ImageView and a vertical LinearLayout that contains two TextView instances:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="?android:attr/listPreferredItemHeight"
    android:padding="5dip">
    <ImageView
        android:id="@+id/icon"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:layout_marginRight="5dip"
        android:src="@drawable/icon" />
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="0dip"
        android:layout_weight="1"
        android:layout_height="fill_parent">
        <TextView
            android:layout_width="fill_parent"
            android:layout_height="0dip"
            android:layout_weight="1"
            android:gravity="center_vertical"
            android:text="Mei tempor iuvaret ad." />
        <TextView
            android:layout_width="fill_parent"
            android:layout_height="0dip"
            android:layout_weight="1"
            android:singleLine="true"
            android:ellipsize="marquee"
            android:text="Lorem ipsum dolor sit amet." />
    </LinearLayout>
</LinearLayout>

Toto rozložení má hloubku 3 úrovně a je wasteful, pokud je pro každý řádek plochý ListView .This layout is 3-levels deep, and is wasteful when inflated for each ListView row. Lze ho však zlepšit sloučením rozložení, jak je znázorněno v následujícím příkladu kódu:However, it can be improved by flattening the layout, as shown in the following code example:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="?android:attr/listPreferredItemHeight"
    android:padding="5dip">
    <ImageView
        android:id="@+id/icon"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:layout_alignParentTop="true"
        android:layout_alignParentBottom="true"
        android:layout_marginRight="5dip"
        android:src="@drawable/icon" />
    <TextView
        android:id="@+id/secondLine"
        android:layout_width="fill_parent"
        android:layout_height="25dip"
        android:layout_toRightOf="@id/icon"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:singleLine="true"
        android:ellipsize="marquee"
        android:text="Lorem ipsum dolor sit amet." />
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/icon"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_above="@id/secondLine"
        android:layout_alignWithParentIfMissing="true"
        android:gravity="center_vertical"
        android:text="Mei tempor iuvaret ad." />
</RelativeLayout>

Předchozí hierarchie 3 úrovně byla snížena na hierarchii 2 a jedna z nich RelativeLayout nahradila dvě LinearLayout instance.The previous 3-level hierarchy has been reduced to a 2-level hierarchy, and a single RelativeLayout has replaced two LinearLayout instances. Výrazné zvýšení výkonu bude získáno při nestrukturovaném rozložení pro každý ListView řádek.A significant performance increase will be gained when inflating the layout for each ListView row.

Optimalizace zobrazení seznamuOptimize List Views

Uživatelé očekávají dobu hladkého posouvání a rychlé načítání ListView instancí.Users expect smooth scrolling and fast load times for ListView instances. Pokud však každý řádek zobrazení seznamu obsahuje hierarchie hluboko vnořeného zobrazení nebo pokud řádky zobrazení seznamu obsahují složitá rozložení, může dojít ke zhoršení výkonu.However, scrolling performance can suffer when each list view row contains deeply nested view hierarchies, or when list view rows contain complex layouts. Existují však techniky, které lze použít k zamezení špatného ListView výkonu:However, there are techniques that can be used to avoid poor ListView performance:

  • Opakované použití zobrazení řádků pro další informace najdete v tématu opakované použití zobrazení řádků.Reuse row views For more information, see Reuse Row Views.
  • Shrnout rozložení, pokud je to možné.Flatten layouts, where possible.
  • Obsah řádku v mezipaměti načtený z webové služby.Cache row content that is retrieved from a web service.
  • Vyhněte se škálování obrázků.Avoid image scaling.

Souhrnně tyto techniky můžou usnadnit ListView plynulé posouvání instancí.Collectively these techniques can help to keep ListView instances scrolling smoothly.

Znovu použít zobrazení řádkůReuse Row Views

Při zobrazení stovek řádků v a ListView by byl odpad paměti pro vytvoření stovek View objektů, když se na obrazovce najednou zobrazuje jenom malý počet.When displaying hundreds of rows in a ListView, it would be a waste of memory to create hundreds of View objects when only a small number of them are displayed on screen at once. Místo toho View lze do paměti načíst pouze objekty viditelné v řádcích na obrazovce s obsahem , který je načítán do těchto znovu používaných objektů.Instead, only the View objects visible in the rows on screen can be loaded into memory, with the content being loaded into these reused objects. Tím se zabrání vytváření instancí stovek dalších objektů a šetří se čas a paměť.This prevents the instantiation of hundreds of additional objects, saving time and memory.

Proto pokud řádek zmizí z obrazovky, lze jeho zobrazení umístit do fronty pro opakované použití, jak je znázorněno v následujícím příkladu kódu:Therefore, when a row disappears from the screen its view can be placed in a queue for reuse, as shown in the following code example:

public override View GetView(int position, View convertView, ViewGroup parent)
{
   View view = convertView; // re-use an existing view, if one is supplied
   if (view == null) // otherwise create a new one
       view = context.LayoutInflater.Inflate(Android.Resource.Layout.SimpleListItem1, null);
   // set view properties to reflect data for the given row
   view.FindViewById<TextView>(Android.Resource.Id.Text1).Text = items[position];
   // return the view, populated with data, for display
   return view;
}

Při posunu uživatele ListView volá GetView přepsání, aby vyžádala nové zobrazení k zobrazení – Pokud je k dispozici, předává nepoužívané zobrazení v convertView parametru.As the user scrolls, the ListView calls the GetView override to request new views to display – if available it passes an unused view in the convertView parameter. Pokud je tato hodnota null , pak kód vytvoří novou View instanci, jinak convertView lze vlastnosti resetovat a znovu použít.If this value is null then the code creates a new View instance, otherwise the convertView properties can be reset and reused.

Další informace najdete v tématu opětovné použití zobrazení řádků při naplňování ovládacího prvku ListView daty.For more information, see Row View Re-Use in Populating a ListView with Data.

Odebrat obslužné rutiny událostí v aktivitáchRemove Event Handlers in Activities

Pokud je aktivita zničena v modulu runtime Androidu, může být stále aktivní v Mono runtime.When an activity is destroyed in the Android runtime, it could still be alive in the Mono runtime. Proto odeberte obslužné rutiny události do externích objektů v, Activity.OnPause aby modul runtime neudržoval odkaz na aktivitu, která byla zničena.Therefore, remove event handlers to external objects in Activity.OnPause to prevent the runtime from keeping a reference to an activity that has been destroyed.

V aktivitě deklarujte obslužné rutiny události na úrovni třídy:In an activity, declare event handler(s) at class level:

EventHandler<UpdatingEventArgs> service1UpdateHandler;

Potom Implementujte obslužné rutiny v aktivitě, například v OnResume :Then implement the handlers in the activity, such as in OnResume:

service1UpdateHandler = (object s, UpdatingEventArgs args) => {
    this.RunOnUiThread (() => {
        this.updateStatusText1.Text = args.Message;
    });
};
App.Current.Service1.Updated += service1UpdateHandler;

Když aktivita ukončí běžící stav, OnPause se zavolá.When the activity exits the running state, OnPause is called. V OnPause implementaci odeberte obslužné rutiny následujícím způsobem:In the OnPause implementation, remove the handlers as follows:

App.Current.Service1.Updated -= service1UpdateHandler;

Omezte životnost služeb.Limit the Lifespan of Services

Po spuštění služby zachová Android spuštěné procesu služby.When a service starts, Android keeps the service process running. Proces bude náročný, protože jeho paměť nemůže být stránkovaná nebo se nepoužila jinde.This makes the process expensive because its memory can't be paged, or used elsewhere. Ponechte službu spuštěnou, pokud není potřeba, a zvyšuje riziko, že aplikace vykazuje špatný výkon kvůli omezením paměti.Leaving a service running when it's not required therefore increases the risk of an application exhibiting poor performance due to memory constraints. Je také možné, že přepínání aplikací je méně efektivní, protože snižuje počet procesů, které může Android ukládat do mezipaměti.It can also make application switching less efficient as it reduces the number of processes Android can cache.

Životnost služby může být omezená pomocí IntentService a, která se sama ukončí, jakmile se zpracuje záměr, který ho spustil.The lifespan of a service can be limited by using an IntentService, which terminates itself once it's handled the intent that started it.

Vydání prostředků při oznámeníRelease Resources when Notified

Během životního cyklu aplikace OnTrimMemory zpětné volání poskytuje oznámení v případě nízké velikosti paměti zařízení.During the application lifecycle, the OnTrimMemory callback provides a notification when the device memory is low. Toto zpětné volání by mělo být implementováno pro příjem následujících oznámení na úrovni paměti:This callback should be implemented to listen for the following memory level notifications:

Kromě toho, když se proces aplikace ukládá do mezipaměti, může zpětné volání přijmout následující oznámení na úrovni paměti OnTrimMemory :In addition, when the application process is cached, the following memory level notifications may be received by the OnTrimMemory callback:

  • TrimMemoryBackground – uvolnění prostředků, které se dají rychle a efektivně znovu sestavit, pokud se uživatel vrátí do aplikace.TrimMemoryBackground – release resources that can be quickly and efficiently rebuilt if the user returns to the app.
  • TrimMemoryModerate – uvolnění prostředků může systému usnadnit udržování dalších procesů v mezipaměti pro lepší celkový výkon.TrimMemoryModerate – releasing resources can help the system keep other processes cached for better overall performance.
  • TrimMemoryComplete – proces aplikace se brzo ukončí, pokud se víc paměti brzo neobnoví.TrimMemoryComplete – the application process will soon be terminated if more memory isn't soon recovered.

Oznámení by měla odpovídat uvolnění prostředků na základě obdržené úrovně.Notifications should be responded to by releasing resources based on the received level.

Uvolnění prostředků v případě, že je uživatelské rozhraní skrytéRelease Resources when the User Interface is Hidden

Uvolněte všechny prostředky, které používá uživatelské rozhraní aplikace v případě, že uživatel přejde do jiné aplikace, protože může významně zvýšit kapacitu Androidu pro procesy v mezipaměti, což zase může mít dopad na kvalitu uživatelského prostředí.Release any resources used by the app's user interface when the user navigates to another app, as it can significantly increase Android's capacity for cached processes, which in turn can have an impact on the user experience quality.

Chcete-li obdržet oznámení, když uživatel ukončí uživatelské rozhraní, implementujte OnTrimMemory zpětné volání ve Activity třídách a naslouchat na TrimMemoryUiHidden úrovni, která indikuje, že uživatelské rozhraní je ze zobrazení skryté.To receive a notification when the user exits the UI, implement the OnTrimMemory callback in Activity classes and listen for the TrimMemoryUiHidden level, which indicates that the UI is hidden from view. Toto oznámení se obdrží jenom v případě, že se všechny součásti uživatelského rozhraní aplikace budou od uživatele skrývat.This notification will be received only when all the UI components of the application become hidden from the user. Uvolnění prostředků uživatelského rozhraní po přijetí tohoto oznámení zajišťuje, že pokud uživatel přejde zpět z jiné aktivity v aplikaci, prostředky uživatelského rozhraní budou stále k dispozici pro rychlé obnovení aktivity.Releasing UI resources when this notification is received ensures that if the user navigates back from another activity in the app, the UI resources are still available to quickly resume the activity.

Optimalizace prostředků obrázkůOptimize Image Resources

Obrázky jsou některé z nejdražších prostředků, které aplikace používají, a jsou často zachyceny s vysokým rozlišením.Images are some of the most expensive resources that applications use, and are often captured at high resolutions. Proto se při zobrazení obrázku zobrazí v rozlišení potřebném pro obrazovku zařízení.Therefore, when displaying an image, display it at the resolution required for the device's screen. Pokud má obrázek vyšší rozlišení než obrazovka, mělo by se škálovat dolů.If the image is of a higher resolution than the screen, it should be scaled down.

Další informace najdete v tématu optimalizace prostředků imagí v průvodci výkonem pro různé platformy .For more information, see Optimize Image Resources in the Cross-Platform Performance guide.

Likvidace nepoužívaných prostředků imagíDispose of Unused Image Resources

Chcete-li ušetřit využití paměti, je vhodné uvolnit velké prostředky imagí, které už nepotřebujete.To save on memory usage, it is a good idea to dispose of large image resources that are no longer needed. Je ale důležité zajistit, aby se image správně odstranily.However, it is important to ensure that images are disposed of correctly. Namísto použití explicitního .Dispose() vyvolání můžete využít příkazy using k zajištění správného použití IDisposable objektů.Instead of using an explicit .Dispose() invocation, you can take advantage of using statements to ensure correct use of IDisposable objects.

Například třída rastrového obrázku implementuje IDisposable .For example, the Bitmap class implements IDisposable. Při zabalení instance BitMap objektu v using bloku je zajištěno, že bude odstraněno správně při ukončení z bloku:Wrapping the instantiation of a BitMap object in a using block ensures that it will be disposed of correctly on exit from the block:

using (Bitmap smallPic = BitmapFactory.DecodeByteArray(smallImageByte, 0, smallImageByte.Length))
{
    // Use the smallPic bit map here
}

Další informace o uvolnění prostředků na jedno použití najdete v tématu vypuštění prostředků IDisposable.For more information about releasing disposable resources, see Release IDisposable Resources.

Vyhnout se aritmetické operace s plovoucí desetinnou čárkouAvoid Floating-Point Arithmetic

V zařízeních s Androidem jsou aritmetické operace s plovoucí desetinnou čárkou přibližně dvojnásobější než celé číslo.On Android devices, floating-point arithmetic is about 2x slower than integer arithmetic. Proto pokud je to možné, nahraďte aritmetické aritmetické aritmetické aritmetické hodnoty.Therefore, replace floating-point arithmetic with integer arithmetic if possible. Nejedná se však o rozdíl mezi časem spuštění float a double aritmetickým vlivem na nedávném hardwaru.However, there's no execution time difference between float and double arithmetic on recent hardware.

Poznámka

I pro aritmetické aritmetické operace některé procesory nemají funkce rozdělení hardwaru.Even for integer arithmetic, some CPUs lack hardware divide capabilities. Proto se v softwaru často provádí operace dělení celých čísel a zbytků.Therefore, integer division and modulus operations are often performed in software.

Zavřít dialogová oknaDismiss Dialogs

Při použití ProgressDialog třídy (nebo jakéhokoli dialogového okna nebo výstrahy) místo volání Hide metody, když je účel dialogu volán, zavolejte Dismiss metodu.When using the ProgressDialog class (or any dialog or alert), instead of calling the Hide method when the dialog's purpose is complete, call the Dismiss method. V opačném případě bude dialogové okno pořád aktivní a tato činnost se nevrátí, když drží odkaz na něj.Otherwise, the dialog will still be alive and will leak the activity by holding a reference to it.

SouhrnSummary

Tento článek popisuje a popisuje techniky pro zvýšení výkonu aplikací vytvořených pomocí Xamarin. Android.This article described and discussed techniques for increasing the performance of applications built with Xamarin.Android. Souhrnně tyto techniky můžou významně snížit množství práce prováděné CPU a množství paměti, které aplikace spotřebovává.Collectively these techniques can greatly reduce the amount of work being performed by a CPU, and the amount of memory consumed by an application.