Çok Çekirdekli Cihazlar & Xamarin.Android
Android birkaç farklı bilgisayar mimarisinde çalışabilir. Bu belgede, bir Xamarin.Android uygulaması için kullanılabilecek farklı CPU mimarileri ele alınmaktadır. Bu belgede, Android uygulamalarının farklı CPU mimarilerini destekleyecek şekilde nasıl paketlenmiş olduğu da açıklanmaktadır. Uygulama İkili Arabirimi (ABI) tanıtılacak ve Xamarin.Android uygulamasında hangi ABI'lerin kullanılacağına ilişkin rehberlik sağlanacaktır.
Genel bakış
Android, birden çok farklı CPU mimarisini destekleyecek makine kodu içeren tek .apk
bir dosya olan "yağ ikili dosyalarının" oluşturulmasını sağlar. Bu, her makine kodu parçasını bir Uygulama İkili Arabirimi ile ilişkilendirerek gerçekleştirilir. ABI, belirli bir donanım cihazında hangi makine kodunun çalıştırılacağını denetlemek için kullanılır. Örneğin, bir Android uygulamasının bir x86 cihazında çalışması için, uygulamayı derlerken x86 ABI desteğinin eklenmesi gerekir.
Özellikle, her Android uygulaması en az bir katıştırılmış uygulama ikili arabirimini (EABI) destekleyecektir. EABI, ekli yazılım programlarına özgü kurallardır. Tipik bir EABI aşağıdakiler gibi şeyleri açıklar:
CPU yönerge kümesi.
Bellek depolarının ve yüklemelerinin bitiş durumu çalışma zamanında.
Nesne dosyalarının ve program kitaplıklarının ikili biçimi ve bu dosya ve kitaplıklarda izin verilen veya desteklenen içerik türleri.
Uygulama kodu ile sistem arasında veri geçirmek için kullanılan çeşitli kurallar (örneğin: işlevler çağrıldığında yazmaçların ve/veya yığının nasıl kullanıldığı, hizalama kısıtlamaları vb.)
Numaralandırma türleri, yapıları, alanları ve dizileri için hizalama ve boyut kısıtlamaları.
Makine kodunuz için genellikle belirli bir kitaplık kümesinden çalışma zamanında kullanılabilen işlev simgelerinin listesi.
armeabi ve diş güvenliği
Uygulama İkili Arabirimi aşağıda ayrıntılı olarak ele alınacaktır, ancak Xamarin.Android tarafından kullanılan çalışma zamanının armeabi
iş parçacığı güvenli olmadığını unutmayın. Desteği olan armeabi
bir uygulama bir armeabi-v7a
cihaza dağıtılırsa, birçok garip ve açıklanamayan özel durum oluşur.
Android 4.0.0, 4.0.1, 4.0.2 ve 4.0.3'teki bir hata nedeniyle, dizin mevcut olsa ve cihaz bir armeabi-v7a
armeabi-v7a
cihaz olsa bile yerel kitaplıklar dizinden armeabi
alınır.
Not
Xamarin.Android, APK'ya doğru sırada eklenmesini sağlar .so
. Bu hata, Xamarin.Android kullanıcıları için bir sorun olmamalıdır.
ABI Açıklamaları
Android tarafından desteklenen her ABI benzersiz bir adla tanımlanır.
armeabi
Bu, en az ARMv5TE yönerge kümesini destekleyen ARM tabanlı CPU'lar için EABI'nin adıdır. Android, küçük endian ARM GNU/Linux ABI'yi izler. Bu ABI donanım destekli kayan nokta hesaplamalarını desteklemez. Tüm FP işlemleri, derleyicinin libgcc.a
statik kitaplığından gelen yazılım yardımcı işlevleri tarafından gerçekleştirilir. SMP cihazları tarafından armeabi
desteklenmez.
Önemli
Xamarin.Android'in armeabi
kodu iş parçacığı açısından güvenli değildir ve çok CPUlu armeabi-v7a
cihazlarda kullanılmamalıdır (aşağıda açıklanmıştır). Kodu tek çekirdekli armeabi-v7a
bir cihazda kullanmak armeabi
güvenlidir.
armeabi-v7a
Bu, yukarıda açıklanan EABI'yi genişleten armeabi
başka bir ARM tabanlı CPU yönerge kümesidir. armeabi-v7a
EABI, donanım kayan nokta işlemleri ve birden çok CPU (SMP) cihazı için destek içerir. EABI kullanan armeabi-v7a
bir uygulama, kullanan armeabi
bir uygulama üzerinde önemli performans iyileştirmeleri bekleyebilir.
Not
armeabi-v7a
makine kodu ARMv5 cihazlarında çalışmaz.
arm64-v8a
Bu, ARMv8 CPU mimarisini temel alan 64 bit yönerge kümesidir. Bu mimari Nexus 9'da kullanılır. Xamarin.Android 5.1 bu mimari için destek kullanıma sunulmuştur (daha fazla bilgi için bkz . 64 bit çalışma zamanı desteği).
x86
Bu, genellikle x86 veya IA-32 adlı yönerge kümesini destekleyen CPU'lar için ABI'nin adıdır. Bu ABI, MMX, SSE, SSE2 ve SSE3 yönerge kümeleri de dahil olmak üzere Pentium Pro yönerge kümesi yönergelerine karşılık gelir. Aşağıdakiler gibi başka isteğe bağlı IA-32 yönerge kümesi uzantısı içermez:
- MOVBE yönergesi.
- Ek SSE3 uzantısı (SSSE3).
- SSE4'ün herhangi bir çeşidi.
Not
Google TV, x86 üzerinde çalıştırılsa da Android'in NDK'sı tarafından desteklenmez.
x86_64
Bu, 64 bit x86 yönerge kümesini (x64 veya AMD64 olarak da adlandırılır) destekleyen CPU'lar için ABI'nin adıdır. Xamarin.Android 5.1 bu mimari için destek kullanıma sunulmuştur (daha fazla bilgi için bkz . 64 bit çalışma zamanı desteği).
APK Dosya Biçimi
Android Uygulama Paketi, bir Android uygulaması için gerekli tüm kodu, varlıkları, kaynakları ve sertifikaları tutan dosya biçimidir. Bu bir .zip
dosyadır, ancak dosya adı uzantısını .apk
kullanır. Genişletildiğinde, Xamarin.Android tarafından oluşturulan bir .apk
dosyanın içeriği aşağıdaki ekran görüntüsünde görülebilir:
Dosyanın içeriğinin .apk
hızlı açıklaması:
AndroidManifest.xml: Bu
AndroidManifest.xml
dosya, ikili XML biçimindedir.classes.dex – Bu, Android çalışma zamanı VM'sinin
dex
kullandığı dosya biçiminde derlenmiş uygulama kodunu içerir.resources.arsc – Bu dosya, uygulama için önceden derlenmiş tüm kaynakları içerir.
lib : Bu dizin her ABI için derlenmiş kodu tutar. Önceki bölümde açıklanan her ABI için bir alt klasör içerir. Yukarıdaki ekran görüntüsünde, söz konusu belgenin
.apk
hem hem dearmeabi-v7a
içinx86
yerel kitaplıkları vardır.META-INF – Bu dizin (varsa) imzalama bilgilerini, paketi ve uzantı yapılandırma verilerini depolamak için kullanılır.
res – Bu dizin, içine
resources.arsc
derlenmemiş kaynakları barındırıyor.
Not
Dosya libmonodroid.so
, tüm Xamarin.Android uygulamaları için gereken yerel kitaplıktır.
Android Cihaz ABI Desteği
Her Android cihazı en fazla iki ABI'de yerel kod yürütmeyi destekler:
"Birincil" ABI – Bu, sistem görüntüsünde kullanılan makine koduna karşılık gelir.
"İkincil" ABI – Bu, sistem görüntüsü tarafından da desteklenen isteğe bağlı bir ABI'dir.
Örneğin, tipik bir ARMv5TE cihazı yalnızca birincil ABI'sine armeabi
sahip olurken, BIR ARMv7 cihazı birincil ABI'sini armeabi-v7a
ve ikincil ABI'sini armeabi
belirtir. Tipik bir x86 cihazı yalnızca birincil ABI değerini x86
belirtir.
Android Yerel Kitaplık Yüklemesi
Paket yükleme zamanında içindeki yerel kitaplıklar .apk
genellikle /data/data/<package-name>/lib
uygulamanın yerel kitaplık dizinine ayıklanır ve bundan sonra olarak $APP/lib
adlandırılır.
Android'in yerel kitaplık yükleme davranışı, Android sürümleri arasında önemli ölçüde farklılık gösterir.
Yerel Kitaplıkları Yükleme: Android 4.0 Öncesi
4.0'dan önceki Android Ice Cream Sandwich, içindeki .apk
tek bir ABI'den yalnızca yerel kitaplıkları ayıklar. Bu vintage Android uygulamaları önce birincil ABI için tüm yerel kitaplıkları ayıklamaya çalışır ve böyle bir kitaplık yoksa Android, ikincil ABI için tüm yerel kitaplıkları ayıklar. "Birleştirme" işlemi yapılmaz.
Örneğin, bir uygulamanın bir cihaza yüklendiği bir armeabi-v7a
durumu göz önünde bulundurun. .apk,
hem hem armeabi-v7a
de armeabi
destekleyen dosyasında aşağıdaki ABI lib
dizinleri ve dosyaları vardır:
lib/armeabi/libone.so
lib/armeabi/libtwo.so
lib/armeabi-v7a/libtwo.so
Yüklemeden sonra yerel kitaplık dizini şunları içerir:
$APP/lib/libtwo.so # from the armeabi-v7a directory in the apk
Başka bir deyişle, yüklü değil libone.so
. Bu, libone.so
uygulamanın çalışma zamanında yüklenmesi için mevcut olmadığından sorunlara neden olur. Bu davranış beklenmeyen bir durum olsa da hata olarak günlüğe kaydedildi ve "amaçlandığı gibi çalışıyor" olarak yeniden sınıflandırıldı.
Sonuç olarak, 4.0'dan önceki Android sürümlerini hedeflerken, uygulamanın destekleyeceği her ABI için tüm yerel kitaplıkların sağlanması gerekir, yani .apk
şunları içermelidir:
lib/armeabi/libone.so
lib/armeabi/libtwo.so
lib/armeabi-v7a/libone.so
lib/armeabi-v7a/libtwo.so
Yerel Kitaplıkları Yükleme: Android 4.0 – Android 4.0.3
Android 4.0 Ice Cream Sandwich ekstraksiyon mantığını değiştirir. Tüm yerel kitaplıkları numaralandırır, dosyanın temel adının zaten ayıklanıp ayıklanmadığını görür ve aşağıdaki koşulların her ikisi de karşılanırsa kitaplık ayıklanır:
Henüz ayıklanmadı.
Yerel kitaplığın ABI değeri hedefin birincil veya ikincil ABI değeriyle eşleşir.
Bu koşulların karşılanması "birleştirme" davranışına olanak tanır; yani, aşağıdaki içeriklere sahip bir'imiz .apk
varsa:
lib/armeabi/libone.so
lib/armeabi/libtwo.so
lib/armeabi-v7a/libtwo.so
Ardından yüklemeden sonra yerel kitaplık dizini şunları içerir:
$APP/lib/libone.so
$APP/lib/libtwo.so
Ne yazık ki, bu davranış aşağıdaki belgede açıklandığı gibi düzene bağlıdır - Sorun 24321: Galaxy Nexus 4.0.2, hem armeabi hem de armeabi-v7a apk'ye dahil edildiğinde armeabi yerel kodunu kullanır.
Yerel kitaplıklar "sırayla" işlenir (örneğin sıkıştırmayı açarak listelendiği gibi) ve ilk eşleşme ayıklanır. öğesinin .apk
içeriği armeabi
ve armeabi-v7a
sürümleri libtwo.so
ve armeabi
ilk olarak listelendiğindenarmeabi
, ayıklanan sürümdür, sürüm değildirarmeabi-v7a
:
$APP/lib/libone.so # armeabi
$APP/lib/libtwo.so # armeabi, NOT armeabi-v7a!
Ayrıca, hem hem de armeabi
armeabi-v7a
ABI'ler belirtiliyor olsa bile (Aşağıda Desteklenen ABI'leri Bildirme bölümünde açıklandığı gibi), Xamarin.Android içinde aşağıdaki öğeyi oluşturur.
csproj
:
<AndroidSupportedAbis>armeabi,armeabi-v7a</AndroidSupportedAbis>
Sonuç olarak, armeabi
libmonodroid.so
ilk olarak içinde .apk
bulunur ve armeabi
libmonodroid.so
hedef için mevcut ve iyileştirilmiş olsa armeabi-v7a
libmonodroid.so
bile ayıklanan olacaktır. Bu, SMP güvenli olmadığından belirsiz çalışma zamanı hatalarıyla armeabi
da sonuçlanabilir.
Yerel Kitaplıkları Yükleme: Android 4.0.4 ve üzeri
Android 4.0.4, ayıklama mantığını değiştirir: tüm yerel kitaplıkları numaralandırır, dosyanın temel adını okur, ardından birincil ABI sürümünü (varsa) veya ikincil ABI'yi (varsa) ayıklar. Bu, "birleştirme" davranışına izin verir; yani, aşağıdaki içeriklere sahip bir'imiz .apk
varsa:
lib/armeabi/libone.so
lib/armeabi/libtwo.so
lib/armeabi-v7a/libtwo.so
Ardından yüklemeden sonra yerel kitaplık dizini şunları içerir:
$APP/lib/libone.so # from armeabi
$APP/lib/libtwo.so # from armeabi-v7a
Xamarin.Android ve ABI'ler
Xamarin.Android aşağıdaki 64 bit mimarileri destekler:
arm64-v8a
x86_64
Not
Ağustos 2018'den itibaren api düzeyi 26'yı hedeflemek için yeni uygulamalar gerekecek ve Ağustos 2019'dan itibaren uygulamaların 32 bit sürüme ek olarak 64 bit sürümleri sağlaması gerekecektir.
Xamarin.Android şu 32 bit mimarileri destekler:
armeabi
^armeabi-v7a
x86
Not
^Xamarin.Android 9.2 itibarıyla armeabi
artık desteklenmemiştir.
Xamarin.Android şu anda için mips
destek sağlamamaktadır.
Desteklenen ABI'leri bildirme
Varsayılan olarak, Xamarin.Android varsayılan olarak armeabi-v7a
Yayın derlemeleri ve armeabi-v7a
Hata ayıklama derlemeleri için olarak x86
ayarlanacaktır. Xamarin.Android projesi için Proje Seçenekleri aracılığıyla farklı ABI'ler için destek ayarlanabilir. Visual Studio'da bu, aşağıdaki ekran görüntüsünde gösterildiği gibi, Proje Özellikleri'nin Android Seçenekleri sayfasında, Gelişmiş sekmesinin altında ayarlanabilir:
Mac için Visual Studio'de desteklenen mimariler, aşağıdaki ekran görüntüsünde gösterildiği gibi, Proje Seçenekleri'nin Android Derleme sayfasında, Gelişmiş sekmesinin altında seçilebilir:
Ek ABI desteği bildirmenin gerekli olabileceği bazı durumlar vardır, örneğin:
Uygulamayı bir
x86
cihaza dağıtma.İş parçacığı güvenliğini sağlamak için uygulamayı bir
armeabi-v7a
cihaza dağıtma.
Özet
Bu belgede, bir Android uygulamasının üzerinde çalışabileceği farklı CPU mimarileri açıklandı. Uygulama İkili Arabirimini ve Android tarafından farklı CPU mimarilerini desteklemek için nasıl kullanıldığını tanıttı.
Daha sonra bir Xamarin.Android uygulamasında ABI desteğinin nasıl belirtileceğini tartışmaya devam etti ve yalnızca için armeabi
tasarlanmış bir armeabi-v7a
cihazda Xamarin.Android uygulamaları kullanılırken ortaya çıkan sorunları vurguladı.