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:
- Düzen Hiyerarşilerini İyileştirme
- Liste Görünümlerini İyileştir
- Etkinliklerdeki Olay İşleyicilerini Kaldırma
- Hizmetlerin Kullanım Ömrünü Sınırlama
- Bildirildiğinde Kaynakları Serbest Bırakma
- Kullanıcı Arabirimi Gizli olduğunda Kaynakları Serbest Bırakma
- Görüntü Kaynaklarını İyileştirme
- Kullanılmayan Görüntü Kaynaklarını Atma
- Kayan Nokta Aritmetiğinden Kaçının
- İletişim Kutularını Kapat
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 ListView
iç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 OnResume
iş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 IntentService
kullanı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:
TrimMemoryRunningModerate
– uygulama bazı gereksiz kaynakları serbest bırakmak isteyebilir .TrimMemoryRunningLow
– uygulama gereksiz kaynakları serbest bırakmalıdır .TrimMemoryRunningCritical
– Uygulama , kritik olmayan işlemleri olabildiğince serbest bırakmalı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.