Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Mendapatkan Informasi Diagnostik
Xamarin.Android memiliki beberapa tempat untuk dilihat saat melacak berbagai bug. Ini termasuk:
- Output MSBuild diagnostik.
- Log penyebaran perangkat.
- Output Log Debug Android.
Output MSBuild Diagnostik
Diagnostik MSBuild dapat berisi informasi tambahan yang berkaitan dengan pembuatan paket dan mungkin berisi beberapa informasi penyebaran paket.
Untuk mengaktifkan output MSBuild diagnostik dalam Visual Studio:
- Klik Opsi Alat > ...
- Di tampilan pohon sebelah kiri, pilih Proyek dan Solusi > Bangun dan Jalankan
- Di panel sebelah kanan, atur dropdown verbositas output build MSBuild ke Diagnostik
- Klik OK
- Bersihkan dan bangun kembali paket Anda.
- Output diagnostik terlihat dalam panel Output.
Untuk mengaktifkan output MSBuild diagnostik dalam Visual Studio untuk Mac/OS X:
- Klik Preferensi Visual Studio untuk Mac > ...
- Di tampilan pohon sebelah kiri, pilih Build Proyek >
- Di panel sebelah kanan, atur menu drop-down Verbositas log ke Diagnostik
- Klik OK
- Mulai ulang Visual Studio untuk Mac
- Bersihkan dan bangun kembali paket Anda.
- Output diagnostik terlihat dalam Errors Pad (View > Pads > Errors ), dengan mengklik tombol Build Output.
Log Penyebaran Perangkat
Untuk mengaktifkan pengelogan penyebaran perangkat dalam Visual Studio:
- Opsi Alat > ...>
- Di tampilan pohon sebelah kiri, pilih Pengaturan Android Xamarin >
- Di panel kanan, aktifkan kotak centang [X] pencatatan debug ekstensi (tulis monodroid.log ke desktop Anda).
- Pesan log ditulis ke file monodroid.log di desktop Anda.
Visual Studio untuk Mac selalu menulis log penyebaran perangkat. FInding mereka sedikit lebih sulit; file log AndroidUtils dibuat untuk setiap hari + waktu penyebaran terjadi, misalnya: AndroidTools-2012-10-24_12-35-45.log.
- Di Windows, file log ditulis ke
%LOCALAPPDATA%\XamarinStudio-{VERSION}\Logs. - Pada OS X, file log ditulis ke
$HOME/Library/Logs/XamarinStudio-{VERSION}.
Android Debug Log Output
Android akan menulis banyak pesan ke Log Debug Android. Xamarin.Android menggunakan properti sistem Android untuk mengontrol pembuatan pesan tambahan ke Android Debug Log. Properti sistem Android dapat diatur melalui perintah setprop dalam Android Debug Bridge (adb):
adb shell setprop PROPERTY_NAME PROPERTY_VALUE
Properti sistem dibaca selama startup proses, dan dengan demikian harus diatur sebelum aplikasi diluncurkan atau aplikasi harus dimulai ulang setelah properti sistem diubah.
Properti Sistem Xamarin.Android
Xamarin.Android mendukung properti sistem berikut:
debug.mono.debug: Jika string yang tidak kosong, ini setara dengan
*mono-debug*.debug.mono.env: Daftar variabel lingkungan yang dipisahkan pipa ('|') untuk diekspor selama startup aplikasi, sebelum mono diinisialisasi. Ini memungkinkan pengaturan variabel lingkungan yang mengontrol pengelogan mono.
Catatan
Karena nilainya '|'dipisahkan, nilai harus memiliki tingkat kutipan tambahan, karena perintah 'adb shell' akan menghapus sekumpulan tanda kutip.
Catatan
Panjang nilai properti sistem Android tidak boleh lebih dari 92 karakter.
Contoh:
adb shell setprop debug.mono.env "'MONO_LOG_LEVEL=info|MONO_LOG_MASK=asm'"debug.mono.log: Daftar komponen yang dipisahkan koma (',') yang harus mencetak pesan tambahan ke Log Debug Android. Secara default, tidak ada yang diatur. Komponennya meliputi:
- semua: Mencetak semua pesan
- gc: Cetak pesan terkait GC.
- gref: Cetak (lemah, global) alokasi referensi dan pesan dealokasi.
- lref: Cetak alokasi referensi lokal dan pesan dealokasi.
Catatan
Ini sangat verbose. Jangan aktifkan kecuali Anda benar-benar perlu.
debug.mono.trace: Memungkinkan pengaturan mono --trace
=PROPERTY_VALUE.
Menghapus bin dan obj
Xamarin.Android telah menderita di masa lalu dari situasi seperti:
- Anda mengalami kesalahan build atau runtime yang aneh.
- Anda
Clean,Rebuild, atau menghapus direktori danobjAndabinsecara manual. - Masalahnya hilang.
Kami sangat berinvestasi untuk memperbaiki masalah seperti ini karena dampaknya pada produktivitas pengembang.
Jika masalah seperti ini terjadi pada Anda:
- Buat catatan mental. Apa tindakan terakhir yang membuat proyek Anda masuk ke status ini?
- Simpan log build Anda saat ini. Coba buat lagi, dan rekam log build diagnostik.
- Kirim laporan bug.
Sebelum menghapus direktori dan obj Andabin, zip dan simpan untuk diagnosis nanti jika diperlukan. Anda mungkin hanya dapat meluangkan Clean proyek aplikasi Xamarin.Android Anda untuk membuat hal-hal berfungsi lagi.
Xamarin.Android tidak dapat mengatasi System.ValueTuple
Kesalahan ini terjadi karena ketidaksesuaian dengan Visual Studio.
Visual Studio 2017 Update 1 (versi 15.1 atau yang lebih lama) hanya kompatibel dengan System.ValueTuple NuGet 4.3.0 (atau yang lebih lama).
Visual Studio 2017 Update 2 (versi 15.2 atau yang lebih baru) hanya kompatibel dengan System.ValueTuple NuGet 4.3.1 (atau yang lebih baru).
Pilih System.ValueTuple NuGet yang benar yang sesuai dengan penginstalan Visual Studio 2017 Anda.
Pesan GC
Pesan komponen GC dapat dilihat dengan mengatur properti sistem debug.mono.log ke nilai yang berisi gc.
Pesan GC dihasilkan setiap kali GC dijalankan dan memberikan informasi tentang berapa banyak pekerjaan yang dilakukan GC:
I/monodroid-gc(12331): GC cleanup summary: 81 objects tested - resurrecting 21.
Informasi GC tambahan seperti informasi waktu dapat dihasilkan dengan mengatur MONO_LOG_LEVEL variabel lingkungan ke debug:
adb shell setprop debug.mono.env MONO_LOG_LEVEL=debug
Ini akan mengakibatkan (banyak) pesan Mono tambahan, termasuk tiga konsekuensi ini:
D/Mono (15723): GC_BRIDGE num-objects 1 num_hash_entries 81226 sccs size 81223 init 0.00ms df1 285.36ms sort 38.56ms dfs2 50.04ms setup-cb 9.95ms free-data 106.54ms user-cb 20.12ms clenanup 0.05ms links 5523436/5523436/5523096/1 dfs passes 1104 6883/11046605
D/Mono (15723): GC_MINOR: (Nursery full) pause 2.01ms, total 287.45ms, bridge 225.60 promoted 0K major 325184K los 1816K
D/Mono ( 2073): GC_MAJOR: (user request) pause 2.17ms, total 2.47ms, bridge 28.77 major 576K/576K los 0K/16K
GC_BRIDGE Dalam pesan, num-objects adalah jumlah objek jembatan yang dipertimbangkan pass ini, dan num_hash_entries merupakan jumlah objek yang diproses selama pemanggilan kode jembatan ini.
GC_MINOR Dalam pesan dan GC_MAJOR , total adalah jumlah waktu saat dunia dijeda (tidak ada utas yang dijalankan), sementara bridge adalah jumlah waktu yang diambil dalam kode pemrosesan jembatan (yang berkaitan dengan Java VM). Dunia tidak dijeda saat pemrosesan jembatan terjadi.
Secara umum, semakin besar nilai num_hash_entries, semakin banyak waktu yang bridge akan diambil koleksi, dan semakin besar waktu yang total dihabiskan untuk dikumpulkan.
Pesan Referensi Global
Untuk mengaktifkan pengelogan Loggig Referensi Global (GREF), properti sistem debug.mono.log harus berisi gref, misalnya:
adb shell setprop debug.mono.log gref
Xamarin.Android menggunakan referensi global Android untuk menyediakan pemetaan antara instans Java dan instans terkelola terkait, seperti saat memanggil metode Java, instans Java perlu disediakan untuk Java.
Sayangnya, emulator Android hanya memungkinkan 2000 referensi global ada pada satu waktu. Perangkat keras memiliki batas referensi global 52000 yang jauh lebih tinggi. Batas bawah bisa bermasalah saat menjalankan aplikasi di emulator, jadi mengetahui dari mana instans berasal bisa sangat berguna.
Catatan
Jumlah referensi global bersifat internal untuk Xamarin.Android, dan tidak (dan tidak dapat) menyertakan referensi global yang diambil oleh pustaka asli lainnya yang dimuat ke dalam proses. Gunakan jumlah referensi global sebagai perkiraan.
I/monodroid-gref(12405): +g+ grefc 108 gwrefc 0 obj-handle 0x40517468/L -> new-handle 0x40517468/L from at Java.Lang.Object.RegisterInstance(IJavaObject instance, IntPtr value, JniHandleOwnership transfer)
I/monodroid-gref(12405): at Java.Lang.Object.SetHandle(IntPtr value, JniHandleOwnership transfer)
I/monodroid-gref(12405): at Java.Lang.Object..ctor(IntPtr handle, JniHandleOwnership transfer)
I/monodroid-gref(12405): at Java.Lang.Thread+RunnableImplementor..ctor(System.Action handler, Boolean removable)
I/monodroid-gref(12405): at Java.Lang.Thread+RunnableImplementor..ctor(System.Action handler)
I/monodroid-gref(12405): at Android.App.Activity.RunOnUiThread(System.Action action)
I/monodroid-gref(12405): at Mono.Samples.Hello.HelloActivity.UseLotsOfMemory(Android.Widget.TextView textview)
I/monodroid-gref(12405): at Mono.Samples.Hello.HelloActivity.<OnCreate>m__3(System.Object o)
I/monodroid-gref(12405): handle 0x40517468; key_handle 0x40517468: Java Type: `mono/java/lang/RunnableImplementor`; MCW type: `Java.Lang.Thread+RunnableImplementor`
I/monodroid-gref(12405): Disposing handle 0x40517468
I/monodroid-gref(12405): -g- grefc 107 gwrefc 0 handle 0x40517468/L from at Java.Lang.Object.Dispose(System.Object instance, IntPtr handle, IntPtr key_handle, JObjectRefType handle_type)
I/monodroid-gref(12405): at Java.Lang.Object.Dispose()
I/monodroid-gref(12405): at Java.Lang.Thread+RunnableImplementor.Run()
I/monodroid-gref(12405): at Java.Lang.IRunnableInvoker.n_Run(IntPtr jnienv, IntPtr native__this)
I/monodroid-gref(12405): at System.Object.c200fe6f-ac33-441b-a3a0-47659e3f6750(IntPtr , IntPtr )
I/monodroid-gref(27679): +w+ grefc 1916 gwrefc 296 obj-handle 0x406b2b98/G -> new-handle 0xde68f4bf/W from take_weak_global_ref_jni
I/monodroid-gref(27679): -w- grefc 1915 gwrefc 294 handle 0xde691aaf/W from take_global_ref_jni
Ada empat pesan konsekuensi:
- Pembuatan referensi global: ini adalah baris yang dimulai dengan +g+ , dan akan menyediakan jejak tumpukan untuk jalur kode pembuatan.
- Penghancuran referensi global: ini adalah baris yang dimulai dengan -g- , dan dapat menyediakan jejak tumpukan untuk jalur kode yang membuang referensi global. Jika GC membuang gref, tidak ada jejak tumpukan yang akan disediakan.
- Pembuatan referensi global yang lemah: ini adalah garis yang dimulai dengan +w+ .
- Penghancuran referensi global yang lemah: ini adalah garis yang dimulai dengan -w- .
Dalam semua pesan, Nilai grefc adalah hitungan referensi global yang telah dibuat Xamarin.Android, sedangkan nilai grefwc adalah hitungan referensi global lemah yang telah dibuat Xamarin.Android. Nilai handle atau obj-handle adalah nilai handle JNI, dan karakter setelah ' ' /adalah jenis nilai handle: /L untuk referensi lokal, /G untuk referensi global, dan /W untuk referensi global yang lemah.
Sebagai bagian dari proses GC, referensi global (+g+) dikonversi menjadi referensi global yang lemah (menyebabkan +w+ dan -g-), GC sisi Java ditendang, dan kemudian referensi global yang lemah diperiksa untuk melihat apakah itu dikumpulkan. Jika masih hidup, gref baru dibuat di sekitar ref lemah (+g+, -w-), jika tidak, ref lemah dihancurkan (-w).
Instans Java dibuat dan dibungkus oleh MCW
I/monodroid-gref(27679): +g+ grefc 2211 gwrefc 0 obj-handle 0x4066df10/L -> new-handle 0x4066df10/L from ...
I/monodroid-gref(27679): handle 0x4066df10; key_handle 0x4066df10: Java Type: `android/graphics/drawable/TransitionDrawable`; MCW type: `Android.Graphics.Drawables.TransitionDrawable`
GC sedang dilakukan...
I/monodroid-gref(27679): +w+ grefc 1953 gwrefc 259 obj-handle 0x4066df10/G -> new-handle 0xde68f95f/W from take_weak_global_ref_jni
I/monodroid-gref(27679): -g- grefc 1952 gwrefc 259 handle 0x4066df10/G from take_weak_global_ref_jni
Objek masih hidup, sebagai handle != null
wref kembali menjadi gref
I/monodroid-gref(27679): *try_take_global obj=0x4976f080 -> wref=0xde68f95f handle=0x4066df10
I/monodroid-gref(27679): +g+ grefc 1930 gwrefc 39 obj-handle 0xde68f95f/W -> new-handle 0x4066df10/G from take_global_ref_jni
I/monodroid-gref(27679): -w- grefc 1930 gwrefc 38 handle 0xde68f95f/W from take_global_ref_jni
Objek mati, sebagai handle == null
wref dibesarkan, tidak ada gref baru yang dibuat
I/monodroid-gref(27679): *try_take_global obj=0x4976f080 -> wref=0xde68f95f handle=0x0
I/monodroid-gref(27679): -w- grefc 1914 gwrefc 296 handle 0xde68f95f/W from take_global_ref_jni
Ada satu kerutan "menarik" di sini: pada target yang menjalankan Android sebelum 4.0, nilai gref sama dengan alamat objek Java dalam memori runtime Android. (Artinya, GC adalah non-bergerak, konservatif, kolektor, dan membagikan referensi langsung ke objek tersebut.) Dengan demikian setelah +g+, +w+, -g-, +g+, -w- urutan, gref yang dihasilkan akan memiliki nilai yang sama dengan nilai gref asli. Ini membuat grepping melalui log cukup mudah.
Android 4.0, bagaimanapun, memiliki kolektor bergerak dan tidak lagi menyerahkan referensi langsung ke objek VM runtime Android. Akibatnya, setelah +g+, +w+, -g-, +g+, -w- urutan, nilai gref akan berbeda. Jika objek bertahan dari beberapa GC, objek akan pergi oleh beberapa nilai gref, sehingga lebih sulit untuk menentukan dari mana instans benar-benar dialokasikan.
Mengkueri Secara Terprogram
Anda dapat mengkueri jumlah GREF dan WREF dengan mengkueri JniRuntime objek.
Java.Interop.JniRuntime.CurrentRuntime.GlobalReferenceCount - Jumlah Referensi Global
Java.Interop.JniRuntime.CurrentRuntime.WeakGlobalReferenceCount - Jumlah Referensi Lemah
Log Debug Android
Log Debug Android dapat memberikan konteks tambahan mengenai kesalahan runtime yang Anda lihat.
Performa Floating-Point sangat mengerikan!
Atau, "Aplikasi saya berjalan 10x lebih cepat dengan build Debug daripada dengan build Rilis!"
Xamarin.Android mendukung beberapa ABI perangkat: armeabi, armeabi-v7a, dan x86. ARI perangkat dapat ditentukan dalam tab Aplikasi Properti > Proyek Arsitektur yang> didukung.
Build debug menggunakan paket Android yang menyediakan semua ABI, dan dengan demikian akan menggunakan ABI tercepat untuk perangkat target.
Build rilis hanya akan menyertakan ARI yang dipilih di tab Properti Proyek. Lebih dari satu dapat dipilih.
armeabi adalah ABI default, dan memiliki dukungan perangkat terluas. Namun, armeabi tidak mendukung perangkat multi-CPU dan titik mengambang perangkat keras, menunjukkan hal-hal lain. Akibatnya, aplikasi yang menggunakan runtime Rilis armeabi akan terikat dengan satu inti dan akan menggunakan implementasi float lunak. Kedua hal ini dapat berkontribusi pada performa yang jauh lebih lambat untuk aplikasi Anda.
Jika aplikasi Anda memerlukan performa floating-point yang layak (misalnya game), Anda harus mengaktifkan armeabi-v7a ABI. Anda mungkin hanya ingin mendukung runtime armeabi-v7a , meskipun ini berarti bahwa perangkat lama yang hanya mendukung armeabi tidak akan dapat menjalankan aplikasi Anda.
Tidak dapat menemukan Android SDK
Ada 2 unduhan yang tersedia dari Google untuk Android SDK untuk Windows. Jika Anda memilih alat penginstal .exe, alat ini akan menulis kunci registri yang memberi tahu Xamarin.Android tempatnya diinstal. Jika Anda memilih file .zip dan membukanya sendiri, Xamarin.Android tidak tahu di mana mencari SDK. Anda dapat memberi tahu Xamarin.Android tempat SDK berada di Visual Studio dengan membuka Opsi > Alat > Xamarin > Pengaturan Android:
IDE tidak menampilkan perangkat target
Terkadang Anda akan mencoba menyebarkan aplikasi Anda ke perangkat, tetapi perangkat yang ingin Anda sebarkan tidak ditampilkan dalam dialog Pilih Perangkat. Ini dapat terjadi ketika Android Debug Bridge memutuskan untuk pergi berlibur.
Untuk mendiagnosis masalah ini, temukan program adb, lalu jalankan:
adb devices
Jika perangkat Anda tidak ada, maka Anda perlu menghidupkan ulang server Android Debug Bridge sehingga perangkat Anda dapat ditemukan:
adb kill-server
adb start-server
Perangkat lunak Sinkronisasi HTC dapat mencegah adb start-server berfungsi dengan baik. Jika perintah adb start-server tidak mencetak port mana yang dimulai, silakan keluar dari perangkat lunak Sinkronisasi HTC dan coba mulai ulang server adb.
Tugas yang ditentukan yang dapat dieksekusi "keytool" tidak dapat dijalankan
Ini berarti bahwa PATH Anda tidak berisi direktori tempat direktori bin Java SDK berada. Periksa apakah Anda mengikuti langkah-langkah tersebut dari panduan Penginstalan .
monodroid.exe atau aresgen.exe keluar dengan kode 1
Untuk membantu Anda men-debug masalah ini, buka Visual Studio dan ubah tingkat verbositas MSBuild, untuk melakukan ini, pilih: Opsi > Alat > Proyek dan Solusi > Bangun dan Jalankan > Verbositas Output Build Proyek MSBuild dan atur nilai ini ke Normal.
Bangun kembali, dan periksa panel Output Visual Studio, yang seharusnya berisi kesalahan penuh.
Ruang penyimpanan pada perangkat tidak cukup untuk menyebarkan paket
Ini terjadi ketika Anda tidak memulai emulator dari dalam Visual Studio. Saat memulai emulator di luar Visual Studio, Anda perlu meneruskan -partition-size 512 opsi, misalnya.
emulator -partition-size 512 -avd MonoDroid
Pastikan Anda menggunakan nama simulator yang benar, yaitu nama yang Anda gunakan saat mengonfigurasi simulator.
INSTALL_FAILED_INVALID_APK saat menginstal paket
Nama paket Android harus berisi titik ('.'). Edit nama paket Anda sehingga berisi titik.
- Dalam Visual Studio:
- Klik kanan Properti proyek > Anda
- Klik tab Manifes Android di sebelah kiri.
- Perbarui bidang Nama paket.
- Jika Anda melihat pesan "Tidak ada AndroidManifest.xml ditemukan. Klik untuk menambahkan satu.", klik tautan lalu perbarui bidang Nama paket.
- Dalam Visual Studio untuk Mac:
- Klik kanan Opsi proyek > Anda.
- Navigasikan ke bagian Aplikasi Build / Android.
- Ubah bidang Nama paket menjadi berisi '.'.
INSTALL_FAILED_MISSING_SHARED_LIBRARY saat menginstal paket
"Shared library" dalam konteks ini bukan file shared library (libfoo.so) asli; itu adalah library yang harus diinstal secara terpisah pada perangkat target, seperti Google Maps.
Paket Android menentukan pustaka bersama mana yang diperlukan dengan <uses-library/> elemen . Jika pustaka yang diperlukan tidak ada pada perangkat target (misalnya //uses-library/@android:required benar, yang merupakan default), maka penginstalan paket akan gagal dengan INSTALL_FAILED_MISSING_SHARED_LIBRARY.
Untuk menentukan pustaka bersama mana yang diperlukan, lihat file AndroidManifest.xml yang dihasilkan(misalnya obj\Debug\android\AndroidManifest.xml) dan cari <uses-library/> elemen. <uses-library/>elemen dapat ditambahkan secara manual dalam file Properties\AndroidManifest.xml proyek Anda dan melalui atribut kustom UsesLibraryAttribute.
Misalnya, menambahkan referensi rakitan ke Mono.Android.GoogleMaps.dll akan secara implisit menambahkan <uses-library/> untuk pustaka bersama Google Maps.
INSTALL_FAILED_UPDATE_INCOMPATIBLE saat menginstal paket
Paket Android memiliki tiga persyaratan:
- Mereka harus berisi '.' (lihat entri sebelumnya)
- Mereka harus memiliki nama paket string unik (oleh karena itu konvensi reverse-tld terlihat di nama aplikasi Android, e.g. com.android.chrome untuk aplikasi Chrome)
- Saat meningkatkan paket, paket harus memiliki kunci penandatanganan yang sama.
Dengan demikian, bayangkan skenario ini:
- Anda membuat & menyebarkan aplikasi sebagai aplikasi Debug
- Anda mengubah kunci penandatanganan, misalnya untuk digunakan sebagai aplikasi Rilis (atau karena Anda tidak menyukai kunci penandatanganan Debug yang disediakan default)
- Anda menginstal aplikasi tanpa menghapusnya terlebih dahulu, misalnya Debug > Mulai Tanpa Debugging dalam Visual Studio
Ketika ini terjadi, penginstalan paket akan gagal dengan kesalahan INSTALL_FAILED_UPDATE_INCOMPATIBLE, karena nama paket tidak berubah saat kunci penandatanganan dilakukan. Log Debug Android juga akan berisi pesan yang mirip dengan:
E/PackageManager( 146): Package [PackageName] signatures do not match the previously installed version; ignoring!
Untuk memperbaiki kesalahan ini, hapus sepenuhnya aplikasi dari perangkat Anda sebelum menginstal ulang.
INSTALL_FAILED_UID_CHANGED saat menginstal paket
Saat paket Android diinstal, paket tersebut diberi id pengguna (UID).
Terkadang, karena alasan yang saat ini tidak diketahui, ketika menginstal melalui aplikasi yang sudah diinstal, penginstalan akan gagal dengan INSTALL_FAILED_UID_CHANGED:
ERROR [2015-03-23 11:19:01Z]: ANDROID: Deployment failed
Mono.AndroidTools.InstallFailedException: Failure [INSTALL_FAILED_UID_CHANGED]
at Mono.AndroidTools.Internal.AdbOutputParsing.CheckInstallSuccess(String output, String packageName)
at Mono.AndroidTools.AndroidDevice.<>c__DisplayClass2c.<InstallPackage>b__2b(Task`1 t)
at System.Threading.Tasks.ContinuationTaskFromResultTask`1.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
Untuk mengatasi masalah ini, hapus paket Android sepenuhnya , baik dengan menginstal aplikasi dari GUI target Android, atau menggunakan adb:
$ adb uninstall @PACKAGE_NAME@
JANGAN GUNAKAN adb uninstall -k, karena ini akan mempertahankan data aplikasi, dan dengan demikian mempertahankan UID yang bertentangan pada perangkat target.
Aplikasi rilis gagal diluncurkan di perangkat
Apakah output Log Debug Android akan berisi pesan yang mirip dengan:
D/AndroidRuntime( 1710): Shutting down VM
W/dalvikvm( 1710): threadid=1: thread exiting with uncaught exception (group=0xb412f180)
E/AndroidRuntime( 1710): FATAL EXCEPTION: main
E/AndroidRuntime( 1710): java.lang.UnsatisfiedLinkError: Couldn't load monodroid: findLibrary returned null
E/AndroidRuntime( 1710): at java.lang.Runtime.loadLibrary(Runtime.java:365)
Jika demikian, ada dua kemungkinan penyebab untuk ini:
.apk tidak menyediakan ABI yang didukung perangkat target. Misalnya, .apk hanya berisi biner armeabi-v7a, dan perangkat target hanya mendukung armeabi.
Bug Android. Jika demikian, hapus instalan aplikasi, silangkan jari Anda, dan instal ulang aplikasi.
Untuk memperbaiki (1), edit Opsi/Properti Proyek dan tambahkan dukungan untuk ABI yang diperlukan ke daftar ABI yang Didukung. Untuk menentukan ABI mana yang perlu Anda tambahkan, jalankan perintah adb berikut terhadap perangkat target Anda:
adb shell getprop ro.product.cpu.abi
adb shell getprop ro.product.cpu.abi2
Output akan berisi ABOR primer (dan sekunder opsional).
$ adb shell getprop | grep ro.product.cpu
[ro.product.cpu.abi2]: [armeabi]
[ro.product.cpu.abi]: [armeabi-v7a]
Properti OutPath tidak diatur untuk proyek "MyApp.csproj"
Ini umumnya berarti Anda memiliki komputer HP dan variabel lingkungan "Platform" telah diatur ke sesuatu seperti MCD atau HPD. Ini bertentangan dengan properti Platform MSBuild yang umumnya diatur ke "CPU Apa pun" atau "x86". Anda harus menghapus variabel lingkungan ini dari komputer Anda sebelum MSBuild dapat berfungsi:
- > Variabel Lingkungan Tingkat Lanjut > Sistem > Panel Kontrol
Mulai ulang Visual Studio atau Visual Studio untuk Mac dan coba bangun ulang. Hal-hal sekarang harus bekerja seperti yang diharapkan.
java.lang.ClassCastException: mono.android.runtime.JavaObject tidak dapat ditransmisikan ke...
Xamarin.Android 4.x tidak benar marshal berlapis jenis generik dengan benar. Misalnya, pertimbangkan kode C# berikut menggunakan SimpleExpandableListAdapter:
// BAD CODE; DO NOT USE
var groupData = new List<IDictionary<string, object>> () {
new Dictionary<string, object> {
{ "NAME", "Group 1" },
{ "IS_EVEN", "This group is odd" },
},
};
var childData = new List<IList<IDictionary<string, object>>> () {
new List<IDictionary<string, object>> {
new Dictionary<string, object> {
{ "NAME", "Child 1" },
{ "IS_EVEN", "This group is odd" },
},
},
};
mAdapter = new SimpleExpandableListAdapter (
this,
groupData,
Android.Resource.Layout.SimpleExpandableListItem1,
new string[] { "NAME", "IS_EVEN" },
new int[] { Android.Resource.Id.Text1, Android.Resource.Id.Text2 },
childData,
Android.Resource.Layout.SimpleExpandableListItem2,
new string[] { "NAME", "IS_EVEN" },
new int[] { Android.Resource.Id.Text1, Android.Resource.Id.Text2 }
);
Masalahnya adalah bahwa Xamarin.Android salah marshal berlapis jenis generik. List<IDictionary<string, object>> sedang di-marshal ke java.lang.ArrrayList, tetapi ArrayList berisi instans (yang mereferensikan Dictionary<string, object> mono.android.runtime.JavaObject instans) alih-alih sesuatu yang mengimplementasikan java.util.Map, menghasilkan pengecualian berikut:
E/AndroidRuntime( 2991): FATAL EXCEPTION: main
E/AndroidRuntime( 2991): java.lang.ClassCastException: mono.android.runtime.JavaObject cannot be cast to java.util.Map
E/AndroidRuntime( 2991): at android.widget.SimpleExpandableListAdapter.getGroupView(SimpleExpandableListAdapter.java:278)
E/AndroidRuntime( 2991): at android.widget.ExpandableListConnector.getView(ExpandableListConnector.java:446)
E/AndroidRuntime( 2991): at android.widget.AbsListView.obtainView(AbsListView.java:2271)
E/AndroidRuntime( 2991): at android.widget.ListView.makeAndAddView(ListView.java:1769)
E/AndroidRuntime( 2991): at android.widget.ListView.fillDown(ListView.java:672)
E/AndroidRuntime( 2991): at android.widget.ListView.fillFromTop(ListView.java:733)
E/AndroidRuntime( 2991): at android.widget.ListView.layoutChildren(ListView.java:1622)
Solusinya adalah menggunakan jenis Koleksi Java yang disediakan alih-alih System.Collections.Generic jenis untuk jenis "dalam". Ini akan menghasilkan jenis Java yang sesuai saat melakukan marshaling instans. (Kode berikut lebih rumit daripada yang diperlukan untuk mengurangi masa pakai gref. Ini dapat disederhanakan untuk mengubah kode asli melalui s/List/JavaList/g dan s/Dictionary/JavaDictionary/g jika masa pakai gref tidak khawatir.)
// insert good code here
using (var groupData = new JavaList<IDictionary<string, object>> ()) {
using (var groupEntry = new JavaDictionary<string, object> ()) {
groupEntry.Add ("NAME", "Group 1");
groupEntry.Add ("IS_EVEN", "This group is odd");
groupData.Add (groupEntry);
}
using (var childData = new JavaList<IList<IDictionary<string, object>>> ()) {
using (var childEntry = new JavaList<IDictionary<string, object>> ())
using (var childEntryDict = new JavaDictionary<string, object> ()) {
childEntryDict.Add ("NAME", "Child 1");
childEntryDict.Add ("IS_EVEN", "This child is odd.");
childEntry.Add (childEntryDict);
childData.Add (childEntry);
}
mAdapter = new SimpleExpandableListAdapter (
this,
groupData,
Android.Resource.Layout.SimpleExpandableListItem1,
new string[] { "NAME", "IS_EVEN" },
new int[] { Android.Resource.Id.Text1, Android.Resource.Id.Text2 },
childData,
Android.Resource.Layout.SimpleExpandableListItem2,
new string[] { "NAME", "IS_EVEN" },
new int[] { Android.Resource.Id.Text1, Android.Resource.Id.Text2 }
);
}
}
NullReferenceExceptions Tak Terduga
Terkadang Log Debug Android akan menyebutkan NullReferenceExceptions bahwa "tidak dapat terjadi", atau berasal dari Kode runtime Mono untuk Android sesaat sebelum aplikasi mati:
E/mono(15202): Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object
E/mono(15202): at Java.Lang.Object.GetObject (IntPtr handle, System.Type type, Boolean owned)
E/mono(15202): at Java.Lang.Object._GetObject[IOnTouchListener] (IntPtr handle, Boolean owned)
E/mono(15202): at Java.Lang.Object.GetObject[IOnTouchListener] (IntPtr handle, Boolean owned)
E/mono(15202): at Android.Views.View+IOnTouchListenerAdapter.n_OnTouch_Landroid_view_View_Landroid_view_MotionEvent_(IntPtr jnienv, IntPtr native__this, IntPtr native_v, IntPtr native_e)
E/mono(15202): at (wrapper dynamic-method) object:b039cbb0-15e9-4f47-87ce-442060701362 (intptr,intptr,intptr,intptr)
or
E/mono ( 4176): Unhandled Exception:
E/mono ( 4176): System.NullReferenceException: Object reference not set to an instance of an object
E/mono ( 4176): at Android.Runtime.JNIEnv.NewString (string)
E/mono ( 4176): at Android.Util.Log.Info (string,string)
Ini dapat terjadi ketika runtime Android memutuskan untuk membatalkan proses, yang dapat terjadi karena sejumlah alasan, termasuk mencapai batas GREF target atau melakukan sesuatu yang "salah" dengan JNI.
Untuk melihat apakah ini masalahnya, periksa Log Debug Android untuk pesan dari proses Anda yang mirip dengan:
E/dalvikvm( 123): VM aborting
Batalkan karena Kelelahan Referensi Global
Lapisan JNI runtime Android hanya mendukung sejumlah referensi objek JNI terbatas agar valid pada titik waktu tertentu. Ketika batas ini terlampaui, hal-hal rusak.
Batas GREF (referensi global) adalah 2000 referensi di emulator, dan ~52000 referensi pada perangkat keras.
Anda tahu bahwa Anda mulai membuat terlalu banyak GREF saat melihat pesan seperti ini di Log Debug Android:
D/dalvikvm( 602): GREF has increased to 1801
Saat Anda mencapai batas GREF, pesan seperti berikut ini dicetak:
D/dalvikvm( 602): GREF has increased to 2001
W/dalvikvm( 602): Last 10 entries in JNI global reference table:
W/dalvikvm( 602): 1991: 0x4057eff8 cls=Landroid/graphics/Point; (20 bytes)
W/dalvikvm( 602): 1992: 0x4057f010 cls=Landroid/graphics/Point; (28 bytes)
W/dalvikvm( 602): 1993: 0x40698e70 cls=Landroid/graphics/Point; (20 bytes)
W/dalvikvm( 602): 1994: 0x40698e88 cls=Landroid/graphics/Point; (20 bytes)
W/dalvikvm( 602): 1995: 0x40698ea0 cls=Landroid/graphics/Point; (28 bytes)
W/dalvikvm( 602): 1996: 0x406981f0 cls=Landroid/graphics/Point; (20 bytes)
W/dalvikvm( 602): 1997: 0x40698208 cls=Landroid/graphics/Point; (20 bytes)
W/dalvikvm( 602): 1998: 0x40698220 cls=Landroid/graphics/Point; (28 bytes)
W/dalvikvm( 602): 1999: 0x406956a8 cls=Landroid/graphics/Point; (20 bytes)
W/dalvikvm( 602): 2000: 0x406956c0 cls=Landroid/graphics/Point; (20 bytes)
W/dalvikvm( 602): JNI global reference table summary (2001 entries):
W/dalvikvm( 602): 51 of Ljava/lang/Class; 164B (41 unique)
W/dalvikvm( 602): 46 of Ljava/lang/Class; 188B (17 unique)
W/dalvikvm( 602): 6 of Ljava/lang/Class; 212B (6 unique)
W/dalvikvm( 602): 11 of Ljava/lang/Class; 236B (7 unique)
W/dalvikvm( 602): 3 of Ljava/lang/Class; 260B (3 unique)
W/dalvikvm( 602): 4 of Ljava/lang/Class; 284B (2 unique)
W/dalvikvm( 602): 8 of Ljava/lang/Class; 308B (6 unique)
W/dalvikvm( 602): 1 of Ljava/lang/Class; 316B
W/dalvikvm( 602): 4 of Ljava/lang/Class; 332B (3 unique)
W/dalvikvm( 602): 1 of Ljava/lang/Class; 356B
W/dalvikvm( 602): 2 of Ljava/lang/Class; 380B (1 unique)
W/dalvikvm( 602): 1 of Ljava/lang/Class; 428B
W/dalvikvm( 602): 1 of Ljava/lang/Class; 452B
W/dalvikvm( 602): 1 of Ljava/lang/Class; 476B
W/dalvikvm( 602): 2 of Ljava/lang/Class; 500B (1 unique)
W/dalvikvm( 602): 1 of Ljava/lang/Class; 548B
W/dalvikvm( 602): 1 of Ljava/lang/Class; 572B
W/dalvikvm( 602): 2 of Ljava/lang/Class; 596B (2 unique)
W/dalvikvm( 602): 1 of Ljava/lang/Class; 692B
W/dalvikvm( 602): 1 of Ljava/lang/Class; 956B
W/dalvikvm( 602): 1 of Ljava/lang/Class; 1004B
W/dalvikvm( 602): 1 of Ljava/lang/Class; 1148B
W/dalvikvm( 602): 2 of Ljava/lang/Class; 1172B (1 unique)
W/dalvikvm( 602): 1 of Ljava/lang/Class; 1316B
W/dalvikvm( 602): 1 of Ljava/lang/Class; 3428B
W/dalvikvm( 602): 1 of Ljava/lang/Class; 3452B
W/dalvikvm( 602): 1 of Ljava/lang/String; 28B
W/dalvikvm( 602): 2 of Ldalvik/system/VMRuntime; 12B (1 unique)
W/dalvikvm( 602): 10 of Ljava/lang/ref/WeakReference; 28B (10 unique)
W/dalvikvm( 602): 1 of Ldalvik/system/PathClassLoader; 44B
W/dalvikvm( 602): 1553 of Landroid/graphics/Point; 20B (1553 unique)
W/dalvikvm( 602): 261 of Landroid/graphics/Point; 28B (261 unique)
W/dalvikvm( 602): 1 of Landroid/view/MotionEvent; 100B
W/dalvikvm( 602): 1 of Landroid/app/ActivityThread$ApplicationThread; 28B
W/dalvikvm( 602): 1 of Landroid/content/ContentProvider$Transport; 28B
W/dalvikvm( 602): 1 of Landroid/view/Surface$CompatibleCanvas; 44B
W/dalvikvm( 602): 1 of Landroid/view/inputmethod/InputMethodManager$ControlledInputConnectionWrapper; 36B
W/dalvikvm( 602): 1 of Landroid/view/ViewRoot$1; 12B
W/dalvikvm( 602): 1 of Landroid/view/ViewRoot$W; 28B
W/dalvikvm( 602): 1 of Landroid/view/inputmethod/InputMethodManager$1; 28B
W/dalvikvm( 602): 1 of Landroid/view/accessibility/AccessibilityManager$1; 28B
W/dalvikvm( 602): 1 of Landroid/widget/LinearLayout$LayoutParams; 44B
W/dalvikvm( 602): 1 of Landroid/widget/LinearLayout; 332B
W/dalvikvm( 602): 2 of Lorg/apache/harmony/xnet/provider/jsse/TrustManagerImpl; 28B (1 unique)
W/dalvikvm( 602): 1 of Landroid/view/SurfaceView$MyWindow; 36B
W/dalvikvm( 602): 1 of Ltouchtest/RenderThread; 92B
W/dalvikvm( 602): 1 of Landroid/view/SurfaceView$3; 12B
W/dalvikvm( 602): 1 of Ltouchtest/DrawingView; 412B
W/dalvikvm( 602): 1 of Ltouchtest/Activity1; 180B
W/dalvikvm( 602): Memory held directly by tracked refs is 75624 bytes
E/dalvikvm( 602): Excessive JNI global references (2001)
E/dalvikvm( 602): VM aborting
Dalam contoh di atas (yang, kebetulan, berasal dari bug 685215) masalahnya adalah bahwa terlalu banyak instans Android.Graphics.Point yang dibuat; lihat komentar #2 untuk daftar perbaikan untuk bug khusus ini.
Biasanya, solusi yang berguna adalah menemukan jenis mana yang memiliki terlalu banyak instans yang dialokasikan - Android.Graphics.Point di cadangan di atas - kemudian temukan tempat instans dibuat dalam kode sumber Anda dan buang dengan tepat (sehingga masa pakai objek Java mereka dipersingkat). Ini tidak selalu sesuai (#685215 multithreaded, sehingga solusi sepele menghindari panggilan Buang), tetapi ini adalah hal pertama yang perlu dipertimbangkan.
Anda dapat mengaktifkan Pengelogan GREF untuk melihat kapan GREF dibuat dan berapa banyak yang ada.
Batalkan karena ketidakcocokan jenis JNI
Jika Anda melakukan hand-roll kode JNI, ada kemungkinan bahwa jenis tidak akan cocok dengan benar, misalnya jika Anda mencoba memanggil java.lang.Runnable.run pada jenis yang tidak mengimplementasikan java.lang.Runnable. Ketika ini terjadi, akan ada pesan yang mirip dengan ini di Log Debug Android:
W/dalvikvm( 123): JNI WARNING: can't call Ljava/Type;;.method on instance of Lanother/java/Type;
W/dalvikvm( 123): in Lmono/java/lang/RunnableImplementor;.n_run:()V (CallVoidMethodA)
...
E/dalvikvm( 123): VM aborting
Dukungan Kode Dinamis
Kode dinamis tidak dikompilasi
Untuk menggunakan C# dinamis di aplikasi atau pustaka, Anda harus menambahkan System.Core.dll, Microsoft.CSharp.dll, dan Mono.CSharp.dll ke proyek Anda.
Dalam Build rilis, MissingMethodException terjadi untuk kode dinamis pada waktu proses.
Kemungkinan proyek aplikasi Anda tidak memiliki referensi ke System.Core.dll, Microsoft.CSharp.dll, atau Mono.CSharp.dll. Pastikan rakitan tersebut dirujuk.
- Perlu diingat bahwa kode dinamis selalu dikenakan biaya. Jika Anda memerlukan kode yang efisien, pertimbangkan untuk tidak menggunakan kode dinamis.
Dalam pratinjau pertama, rakitan tersebut dikecualikan kecuali jenis di setiap rakitan secara eksplisit digunakan oleh kode aplikasi. Lihat hal berikut ini untuk solusinya: http://lists.ximian.com/pipermail/mo...il/009798.html
Proyek yang dibangun dengan crash AOT+LLVM pada perangkat x86
Saat menyebarkan aplikasi yang dibangun dengan AOT+LLVM pada perangkat berbasis x86, Anda mungkin melihat pesan kesalahan pengecualian yang mirip dengan yang berikut ini:
Assertion: should not be reached at /Users/.../external/mono/mono/mini/tramp-x86.c:124
Fatal signal 6 (SIGABRT), code -6 in tid 4051 (Xamarin.bug56111)
Ini adalah masalah yang diketahui - solusinya adalah menonaktifkan LLVM.
