Aracılığıyla paylaş


Xamarin.Android Performansı

Xamarin.Android ile oluşturulan uygulamaların performansını artırmaya yönelik birçok teknik vardır. Bu teknikler toplu olarak bir CPU tarafından gerçekleştirilen çalışma miktarını ve bir uygulama tarafından kullanılan bellek miktarını büyük ölçüde azaltabilir. Bu makalede bu teknikler açıklanır ve ele alınmaktadır.

Performansa Genel Bakış

Kötü uygulama performansı birçok şekilde kendini gösterir. Bir uygulamanın yanıt vermemeye başlamasına neden olabilir, yavaş kaydırmaya neden olabilir ve pil ömrünü azaltabilir. Ancak performansı iyileştirmek, yalnızca verimli kod uygulamaktan fazlasını içerir. Kullanıcının uygulama performansı deneyimi de dikkate alınmalıdır. Örneğin, işlemlerin kullanıcının diğer etkinlikleri gerçekleştirmesini engellemeden yürütülmesini sağlamak, kullanıcının deneyimini geliştirmeye yardımcı olabilir.

Xamarin.Android ile oluşturulan uygulamaların performansını ve algılanan performansı artırmaya yönelik bir dizi teknik vardır. Bu ölçümler şunlardır:

Not

Bu makaleyi okumadan önce, Xamarin platformu kullanılarak oluşturulan uygulamaların bellek kullanımını ve performansını geliştirmek için platforma özgü olmayan tekniklerin açıklandığı Platformlar Arası Performans makalesini okumalısınız.

Düzen Hiyerarşilerini İyileştirme

Bir uygulamaya eklenen her düzen için başlatma, düzen ve çizim gerekir. Her alt öğe iki kez ölçüleceği için, parametresini weight kullanan örnekleri iç içe LinearLayout geçirirken düzen geçişi pahalı olabilir. öğesinin LinearLayout iç içe geçmiş örneklerinin kullanılması derin bir görünüm hiyerarşisine yol açabilir ve bu da gibi birden çok kez şişirilen düzenler için düşük performansa neden olabilir.ListView Bu nedenle, performans avantajları daha sonra çarpılacağı için bu tür düzenlerin iyileştirilmiş olması önemlidir.

Örneğin, simge, başlık ve açıklama içeren liste görünümü satırı için öğesini göz önünde bulundurun LinearLayout . , LinearLayout iki TextView örnek içeren bir ImageView ve dikey LinearLayout içerir:

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

Bu düzen 3 düzey derinliğindedir ve her ListView satır için şişirildiğinde boşa harcanmış olur. Ancak, aşağıdaki kod örneğinde gösterildiği gibi düzeni düzleştirme yoluyla geliştirilebilir:

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

Önceki 3 düzeyli hiyerarşi 2 düzeyli hiyerarşiye indirgenmiş ve tek RelativeLayout bir örnek iki LinearLayout örneğin yerini almıştır. Her ListView satır için düzen şişirilirken önemli bir performans artışı elde edilir.

Liste Görünümlerini İyileştir

Kullanıcılar, örnekler için ListView sorunsuz kaydırma ve hızlı yükleme süreleri bekler. Ancak, her liste görünümü satırı iç içe görünüm hiyerarşileri içerdiğinde veya liste görünümü satırları karmaşık düzenler içerdiğinde kaydırma performansı zarar görebilir. Ancak, düşük ListView performansı önlemek için kullanılabilecek teknikler vardır:

  • Satır görünümlerini yeniden kullanma Daha fazla bilgi için bkz . Satır Görünümlerini Yeniden Kullanma.
  • Mümkün olduğunca düzenleri düzleştirme.
  • Bir web hizmetinden alınan satır içeriğini önbelleğe alın.
  • Görüntü ölçeklendirmekten kaçının.

Bu teknikler toplu olarak örneklerin sorunsuz bir şekilde kaydırılmasında yardımcı ListView olabilir.

Satır Görünümlerini Yeniden Kullan

bir ListViewiçinde yüzlerce satır görüntülerken, aynı anda ekranda yalnızca az sayıda nesne görüntülendiğinde yüzlerce View nesne oluşturmak bellek kaybı olur. Bunun yerine, yalnızca View ekrandaki satırlarda görünen nesneler belleğe yüklenebilir ve içerik bu yeniden kullanılan nesnelere yüklenir. Bu, yüzlerce ek nesnenin örneklenmesini önleyerek zaman ve bellek tasarrufu sağlar.

Bu nedenle, aşağıdaki kod örneğinde gösterildiği gibi bir satır ekrandan kaybolduğunda görünümü yeniden kullanmak üzere bir kuyruğa yerleştirilebilir:

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;
}

Kullanıcı kaydırılırken, ListView yeni görünümlerin GetView görüntülenmesini istemek için geçersiz kılmayı çağırır; varsa parametresinde convertView kullanılmayan bir görünüm geçirir. Bu değer ise null kod yeni View bir örnek oluşturur, aksi takdirde convertView özellikler sıfırlanabilir ve yeniden kullanılabilir.

Daha fazla bilgi için bkz. ListView'ı Verilerle Doldurmada Satır Görünümü Yeniden Kullanma.

Etkinliklerdeki Olay İşleyicilerini Kaldırma

Android çalışma zamanında bir etkinlik yok edildiğinde Mono çalışma zamanında hala canlı olabilir. Bu nedenle, çalışma zamanının yok edilmiş bir etkinliğe başvuruyu korumasını önlemek için içindeki dış nesnelere Activity.OnPause olay işleyicilerini kaldırın.

Bir etkinlikte, sınıf düzeyinde olay işleyicilerini bildirin:

EventHandler<UpdatingEventArgs> service1UpdateHandler;

Ardından , gibi bir etkinlikte OnResumeişleyicileri uygulayın:

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

Etkinlik çalışma durumundan çıktığında çağrılır OnPause . OnPause Uygulamada, işleyicileri aşağıdaki gibi kaldırın:

App.Current.Service1.Updated -= service1UpdateHandler;

Hizmetlerin Kullanım Ömrünü Sınırlama

Bir hizmet başlatıldığında Android, hizmet işlemini çalışır durumda tutar. Bu, belleği disk belleğine alınamadığı veya başka bir yerde kullanılamadığı için işlemi pahalı hale getirir. Bu nedenle, gerekli olmadığında bir hizmetin çalışır durumda bırakılması, bellek kısıtlamaları nedeniyle uygulamanın düşük performans sergilemesi riskini artırır. Ayrıca Android'in önbelleğe alabildiği işlem sayısını azalttığı için uygulama geçişinin daha az verimli olmasını sağlayabilir.

Hizmetin kullanım ömrü, hizmeti başlatan amaç işlendikten sonra kendisini sonlandıran bir IntentServicekullanılarak sınırlandırılabilir.

Bildirildiğinde Kaynakları Serbest Bırakma

Uygulama yaşam döngüsü sırasında geri arama, OnTrimMemory cihaz belleği düşük olduğunda bir bildirim sağlar. Bu geri çağırma aşağıdaki bellek düzeyi bildirimlerini dinlemek için uygulanmalıdır:

Ayrıca, uygulama işlemi önbelleğe alındığında, geri çağırma tarafından OnTrimMemory aşağıdaki bellek düzeyi bildirimleri alınabilir:

  • TrimMemoryBackground – kullanıcı uygulamaya geri döndüğünde hızlı ve verimli bir şekilde yeniden oluşturulabilen kaynakları serbest bırakın.
  • TrimMemoryModerate – kaynakların serbest bırakılması, sistemin daha iyi bir genel performans için diğer işlemleri önbelleğe almalarına yardımcı olabilir.
  • TrimMemoryComplete – Daha fazla bellek kısa süre içinde kurtarılamazsa uygulama işlemi yakında sonlandırılır.

Alınan düzeye göre kaynaklar serbest bırakılarak bildirimlere yanıt verilmelidir.

Kullanıcı Arabirimi Gizli olduğunda Kaynakları Serbest Bırakma

Kullanıcı başka bir uygulamaya gittiği zaman uygulamanın kullanıcı arabirimi tarafından kullanılan tüm kaynakları serbest bırakın, çünkü Android'in önbelleğe alınmış işlemler için kapasitesini önemli ölçüde artırabilir ve bu da kullanıcı deneyimi kalitesini etkileyebilir.

Kullanıcı kullanıcı arabiriminden çıktığında bildirim almak için, sınıflarda Activity geri çağırmayı OnTrimMemory uygulayın ve kullanıcı arabiriminin TrimMemoryUiHidden görünümden gizlendiğini gösteren düzeyi dinleyin. Bu bildirim yalnızca uygulamanın tüm kullanıcı arabirimi bileşenleri kullanıcıdan gizlendiğinde alınır. Bu bildirim alındığında kullanıcı arabirimi kaynaklarının serbest bırakılması, kullanıcının uygulamadaki başka bir etkinlikten geri dönmesi durumunda kullanıcı arabirimi kaynaklarının etkinliği hızlı bir şekilde sürdürmek için kullanılabilir durumda olmasını sağlar.

Görüntü Kaynaklarını İyileştirme

Görüntüler, uygulamaların kullandığı en pahalı kaynaklardan bazılarıdır ve genellikle yüksek çözünürlüklerde yakalanır. Bu nedenle, bir görüntüyü görüntülerken cihazın ekranı için gereken çözünürlükte görüntüleyin. Görüntü ekrandan daha yüksek çözünürlükteyse ölçeği azaltılmalıdır.

Daha fazla bilgi için Platformlar Arası Performans kılavuzundaki Görüntü Kaynaklarını İyileştirme bölümüne bakın.

Kullanılmayan Görüntü Kaynaklarını Atma

Bellek kullanımından tasarruf etmek için artık gerekli olmayan büyük görüntü kaynaklarını atmak iyi bir fikirdir. Ancak, görüntülerin doğru şekilde atıldığından emin olmak önemlidir. Açık .Dispose() bir çağırma kullanmak yerine, nesnelerin doğru kullanıldığından emin olmak için deyimleri kullanma avantajından IDisposable yararlanabilirsiniz.

Örneğin, Bit Eşlem sınıfı uygular IDisposable. Bir BitMap nesnenin örneğini bir using blokta sarmalama, bloktan çıkışta doğru şekilde atılmasını sağlar:

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

Atılabilir kaynakları yayınlama hakkında daha fazla bilgi için bkz . IDisposable Kaynaklarını Serbest Bırakma.

Kayan Nokta Aritmetiğinden Kaçının

Android cihazlarda kayan nokta aritmetiği tamsayı aritmetiğinden yaklaşık 2 kat daha yavaştır. Bu nedenle, kayan nokta aritmetiğini mümkünse tamsayı aritmetiğiyle değiştirin. Ancak, son donanımlarda ve double aritmetik arasında float yürütme süresi farkı yoktur.

Not

Tamsayı aritmetiği için bile bazı CPU'larda donanım bölme özellikleri eksiktir. Bu nedenle, tamsayı bölme ve modül işlemleri genellikle yazılımda gerçekleştirilir.

İletişim Kutularını Kapat

sınıfını ProgressDialog (veya herhangi bir iletişim kutusunu veya uyarıyı) kullanırken, iletişim kutusunun amacı tamamlandığında yöntemini çağırmak Hide yerine yöntemini çağırın Dismiss . Aksi takdirde, iletişim kutusu hala etkin olur ve bir başvuru tutarak etkinliği sızdıracaktır.

Özet

Bu makalede, Xamarin.Android ile oluşturulan uygulamaların performansını artırmaya yönelik teknikler açıklanmış ve ele alınmaktadır. Bu teknikler toplu olarak bir CPU tarafından gerçekleştirilen çalışma miktarını ve bir uygulama tarafından kullanılan bellek miktarını büyük ölçüde azaltabilir.