Aracılığıyla paylaş


Ç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 thread Kasa ty

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-v7aarmeabi-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 armeabidesteklenmez.

Ö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 armeabibir 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:

Contents of the .apk

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 de armeabi-v7a için x86 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 armeabisahip olurken, BIR ARMv7 cihazı birincil ABI'sini armeabi-v7a ve ikincil ABI'sini armeabibelirtir. Tipik bir x86 cihazı yalnızca birincil ABI değerini x86belirtir.

Android Yerel Kitaplık Yüklemesi

Paket yükleme zamanında içindeki yerel kitaplıklar .apk genellikle /data/data/<package-name>/libuygulamanın yerel kitaplık dizinine ayıklanır ve bundan sonra olarak $APP/libadlandı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 .apktek 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-v7ade 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.sove 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 armeabiarmeabi-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, armeabilibmonodroid.so ilk olarak içinde .apkbulunur ve armeabilibmonodroid.so hedef için mevcut ve iyileştirilmiş olsa armeabi-v7alibmonodroid.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 mipsdestek 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:

Android Options Advanced properties

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:

Android Build Supported ABIs

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 armeabitasarlanmış bir armeabi-v7a cihazda Xamarin.Android uygulamaları kullanılırken ortaya çıkan sorunları vurguladı.