Výkon Xamarin. Android

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.

Přehled výkonu

Nízký výkon aplikace prezentuje mnoho způsobů. 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. Optimalizace výkonu však zahrnuje více než pouze implementaci efektivního kódu. Také je nutné vzít v úvahu činnost uživatele při výkonu aplikace. 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í.

Existuje několik postupů pro zvýšení výkonu a zjištěného výkonu aplikací vytvořených pomocí Xamarin. Android. Mezi ně patří:

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.

Optimalizace hierarchií rozložení

Každé rozložení přidané do aplikace vyžaduje inicializaci, rozložení a vykreslení. Ú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. 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 . Proto je důležité, aby taková rozložení byla optimalizována, protože výhody výkonu budou vynásobeny.

Zvažte LinearLayout například řádek pro zobrazení seznamu, který má ikonu, název a popis. LinearLayoutBude obsahovat ImageView a svislou LinearLayout , která obsahuje dvě TextView instance:

<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ý ListView řádek plochý. 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:

<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 RelativeLayout z nich nahradila dvě LinearLayout instance. Výrazné zvýšení výkonu bude získáno při nestrukturovaném rozložení pro každý ListView řádek.

Optimalizace zobrazení seznamu

Uživatelé očekávají dobu ListView hladkého posouvání a rychlé načítání instancí. 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. Existují však techniky, které lze použít k zamezení špatného ListView výkonu:

  • Opakované použití zobrazení řádků pro další informace najdete v tématu opakované použití zobrazení řádků.
  • Shrnout rozložení, pokud je to možné.
  • Obsah řádku v mezipaměti načtený z webové služby.
  • Vyhněte se škálování obrázků.

Souhrnně tyto techniky můžou usnadnit ListView plynulé posouvání instancí.

Znovu použít zobrazení řádků

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. Místo toho lze do paměti načíst pouze View objekty viditelné v řádcích na obrazovce s View , který je načítán do těchto znovu používaných objektů. Tím se zabrání vytváření instancí stovek dalších objektů a šetří se čas a paměť.

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:

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 volá GetView přepsání, ListView aby vyžádala nové zobrazení k zobrazení – Pokud je k dispozici, předává nepoužívané zobrazení v convertView parametru. Pokud je null Tato hodnota, pak kód vytvoří novou View instanci, jinak convertView lze vlastnosti resetovat a znovu použít.

Další informace najdete v tématu opětovné použití zobrazení řádků při naplňování ovládacího prvku ListView daty.

Odebrat obslužné rutiny událostí v aktivitách

Pokud je aktivita zničena v modulu runtime Androidu, může být stále aktivní v 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.

V aktivitě deklarujte obslužné rutiny události na úrovni třídy:

EventHandler<UpdatingEventArgs> service1UpdateHandler;

Potom Implementujte obslužné rutiny v aktivitě, například v 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á. OnPauseV implementaci odeberte obslužné rutiny následujícím způsobem:

App.Current.Service1.Updated -= service1UpdateHandler;

Omezte životnost služeb.

Po spuštění služby zachová Android spuštěné procesu služby. Proces bude náročný, protože jeho paměť nemůže být stránkovaná nebo se nepoužila jinde. 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. 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.

Životnost služby může být omezená pomocí IntentService a, která se sama ukončí, jakmile se zpracuje záměr, který ho spustil.

Vydání prostředků při oznámení

Během životního cyklu OnTrimMemory aplikace zpětné volání poskytuje oznámení v případě nízké velikosti paměti zařízení. 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:

Kromě toho, když se proces aplikace ukládá do mezipaměti, může zpětné volání přijmout OnTrimMemory následující oznámení na úrovni paměti:

  • TrimMemoryBackground – uvolnění prostředků, které se dají rychle a efektivně znovu sestavit, pokud se uživatel vrátí do aplikace.
  • TrimMemoryModerate – uvolnění prostředků může systému usnadnit udržování dalších procesů v mezipaměti pro lepší celkový výkon.
  • TrimMemoryComplete – proces aplikace se brzo ukončí, pokud se víc paměti brzo neobnoví.

Oznámení by měla odpovídat uvolnění prostředků na základě obdržené úrovně.

Uvolnění prostředků v případě, že je uživatelské rozhraní skryté

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í.

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é. 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. 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.

Optimalizace prostředků obrázků

Obrázky jsou některé z nejdražších prostředků, které aplikace používají, a jsou často zachyceny s vysokým rozlišením. Proto se při zobrazení obrázku zobrazí v rozlišení potřebném pro obrazovku zařízení. Pokud má obrázek vyšší rozlišení než obrazovka, mělo by se škálovat dolů.

Další informace najdete v tématu optimalizace prostředků imagí v průvodci výkonem pro různé platformy .

Likvidace nepoužívaných prostředků imagí

Chcete-li ušetřit využití paměti, je vhodné uvolnit velké prostředky imagí, které už nepotřebujete. Je ale důležité zajistit, aby se image správně odstranily. Namísto použití explicitního .Dispose() vyvolání můžete využít příkazy .Dispose() k zajištění správného použití IDisposable objektů.

Například třída rastrového obrázku implementuje . 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:

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.

Vyhněte se Floating-Point aritmetické operace

V zařízeních s Androidem jsou aritmetické operace s plovoucí desetinnou čárkou přibližně dvojnásobější než celé číslo. Proto pokud je to možné, nahraďte aritmetické aritmetické aritmetické aritmetické hodnoty. Nejedná se však o rozdíl mezi float časem spuštění a double aritmetickým vlivem na nedávném hardwaru.

Poznámka

I pro aritmetické aritmetické operace některé procesory nemají funkce rozdělení hardwaru. Proto se v softwaru často provádí operace dělení celých čísel a zbytků.

Zavřít dialogová okna

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. V opačném případě bude dialogové okno pořád aktivní a tato činnost se nevrátí, když drží odkaz na něj.

Souhrn

Tento článek popisuje a popisuje techniky pro zvýšení výkonu 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á.