Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Android kitaplığını ( .aar veya .jar) bağlamak nadiren basit bir iştir; Genellikle Java ile .NET arasındaki farklardan kaynaklanan sorunları azaltmak için ek çaba gerektirir. Bu sorunlar, Android için .NET'in Android kitaplığını bağlamasını ve kendilerini derleme günlüğünde hata iletileri olarak göstermesini engeller. Bu kılavuz, sorunları gidermeye yönelik bazı ipuçları sağlar, daha yaygın sorunlardan/senaryolardan bazılarını listeler ve Android kitaplığını başarıyla bağlamaya yönelik olası çözümler sağlar.
Mevcut bir Android kitaplığını bağlarken aşağıdaki noktaları göz önünde bulundurmak gerekir:
Kitaplığın dış bağımlılıkları – Android kitaplığı için gereken tüm Java bağımlılıkları, NuGet paketi aracılığıyla veya AndroidLibrary olarak Android için .NET projesine dahil edilmelidir.
Android kitaplığının hedeflediği Android API düzeyi – Android API düzeyini "düşürmek" mümkün değildir; Android için .NET bağlama projesinin Android kitaplığıyla aynı API düzeyini (veya üstünü) hedeflediğinden emin olun.
Tavsiye
Bağlama Araçları GitHub deposu wiki'si harika bir kaynaktır ve belirli durumlarda yardımcı olabilecek ek sorun giderme bilgileri içerir.
Android için .NET kitaplığı bağlamayla ilgili sorunları gidermenin ilk adımı , tanılama MSBuild çıkışını etkinleştirmektir. Tanılama çıkışını etkinleştirdikten sonra Android için .NET bağlama projesini yeniden derleyin ve sorunun nedeninin ne olduğuna ilişkin ipuçlarını bulmak için derleme günlüğünü inceleyin.
Ayrıca Android kitaplığını derlemek ve Android için .NET'in bağlamaya çalıştığı türleri ve yöntemleri incelemek yararlı olabilir. Bu, bu kılavuzun ilerleyen bölümlerinde daha ayrıntılı olarak ele alınmıştır.
Android kitaplığını geri çözümleme
Java sınıflarının sınıflarını ve yöntemlerini incelemek, kitaplığı bağlamaya yardımcı olacak değerli bilgiler sağlayabilir. JD-GUI , JAR'da yer alan CLASS dosyalarından Java kaynak kodunu görüntüleyebilen bir grafik yardımcı programıdır.
Android kitaplığının kodunu çözmek için .JAR dosyasını Java ayrıştırıcısı ile açın. Eğer kitaplık bir .AAR dosyasıysa, Java kaynak kodu arşiv dosyasının classes.jar girdisinde yer alır. Picasso JAR'ı analiz etmek için JD-GUI kullanmanın örnek ekran görüntüsü aşağıda verilmiştir:
Android kitaplığını derledikten sonra kaynak kodu inceleyin. Genel olarak konuşursak, şunlara dikkat edin:
Karartma özelliklerine sahip sınıflar – Karartılmış sınıfların özellikleri şunlardır:
- Sınıf adı bir $içerir; örneğin , a$.class
- Sınıf adı tamamen küçük harfli karakterlerden oluşur, yani a.class
importbaşvurulmayan kitaplıklar için deyimler – Başvurulmayan kitaplığı tanımlayın ve bu bağımlılıkları NuGet'ten uygun bir bağlamayla veya AndroidLibraryDerleme Eylemi ile Android için .NET bağlama projesine ekleyin.
Uyarı
Java kitaplığını derlemek yasaklanabilir veya yerel yasalara veya Java kitaplığının yayımlandığı lisansa bağlı olarak yasal kısıtlamalara tabi olabilir. Gerekirse, bir Java kütüphanesini decompile etmeye ve kaynak kodunu incelemeye çalışmadan önce bir hukuk uzmanının hizmetlerinden yararlanın.
api.xml denetleme
Bağlama projesi oluşturmanın bir parçası olarak, Android için .NET obj/Debug/api.xmlbir XML dosya adı oluşturur:
Bu dosya, Android için .NET'in bağlamaya çalıştığı tüm Java API'lerinin listesini sağlar. Bu dosyanın içeriği, eksik türleri veya yöntemleri ve yinelenen bağlamayı tanımlamaya yardımcı olabilir. Bu dosyanın incelenmesi yorucu ve zaman alıcı olsa da, bağlama sorunlarına neyin neden olabileceği hakkında ipuçları sağlayabilir. Örneğin ,api.xml bir özelliğin uygunsuz bir tür döndürdüğünü veya aynı yönetilen adı paylaşan iki tür olduğunu gösterebilir.
Bilinen sorunlar
Bu bölümde, Bir Android kitaplığını bağlamaya çalışırken oluşan bazı yaygın hata iletileri veya belirtiler listelenecektir.
Sorun: Oluşturulan çıktıda eksik C# türleri.
Bağlama .dll derleniyor fakat bazı Java türlerini kaçırıyor veya üretilen C# kaynağı eksik türler olduğunu belirten bir hata nedeniyle derlenmiyor.
Olası nedenler:
Bu hata, aşağıda listelenen çeşitli nedenlerden kaynaklanabilir:
Bağlı olan kitaplık ikinci bir Java kitaplığına başvurabilir. Bağlanmış kitaplığın genel API'sinde ikinci kitaplıktan türler kullanılıyorsa, ikinci kitaplık için de yönetilen bağlantıya başvurmanız gerekir.
Java, genel olmayan bir sınıftan genel sınıf türetmeye izin verir, ancak bu .NET'te desteklenmez. Bağlama oluşturucu ortak olmayan sınıflar için bağlamalar oluşturmadığından, bunlar gibi türetilmiş sınıflar doğru oluşturulamaz. Bunu düzeltmek için, Metadata.xmliçindeki remove-node kullanarak türetilmiş sınıfların meta veri girdisini kaldırın veya genel olmayan sınıfı genel yapan meta verileri düzeltin. İkinci çözüm C# kaynağının derlenmesi için bağlamayı oluştursa da, ortak olmayan sınıf kullanılmamalıdır.
Örneğin:
<attr path="/api/package[@name='com.some.package']/class[@name='SomeClass']" name="visibility">public</attr>Java kitaplıklarını gizleyen araçlar, Android için .NET Bağlama Oluşturucu'ya ve C# sarmalayıcı sınıfları oluşturma özelliğine müdahale edebilir. Aşağıdaki kod parçacığı, Metadata.xml dosyasını sınıf adını açık hale getirecek şekilde nasıl güncelleştireceğinizi gösterir.
<attr path="/api/package[@name='{package_name}']/class[@name='{name}']" name="obfuscated">false</attr>
Sorun: Oluşturulan C# kaynağı parametre türü uyuşmazlığı nedeniyle oluşturulmuyor
Oluşturulan C# kodu derlenmiyor. Geçersiz kılınan yöntemin parametre türleri eşleşmiyor.
Olası nedenler:
Android için .NET, C# bağlamalarındaki sabit listeleriyle eşlenen çeşitli Java alanları içerir. Bunlar, oluşturulan bağlamalarda tür uyumsuzluklarına neden olabilir. Bunu çözmek için, bağlama oluşturucu tarafından oluşturulan yöntem imzalarının enumları kullanacak şekilde değiştirilmesi gerekir. Daha fazla bilgi için bkz. Numaralandırma oluşturma.
Sorun: Yinelenen özel EventArgs türleri
Yinelenen özel EventArgs türleri nedeniyle derleme başarısızlıkla sonuçlanıyor. Aşağıdaki gibi bir hata oluşur:
error CS0102: The type `Com.Google.Ads.Mediation.DismissScreenEventArgs' already contains a definition for `p0'
Olası nedenler:
Bunun nedeni, aynı adlara sahip yöntemleri paylaşan birden fazla arabirim "dinleyicisi" türünden gelen olay türleri arasında bazı çakışmalar olmasıdır. Örneğin, aşağıdaki örnekte görüldüğü gibi iki Java arabirimi varsa, oluşturucu MediationBannerListener ve MediationInterstitialListener için DismissScreenEventArgs oluşturur ve bu da hatayla sonuçlanır.
// Java:
public interface MediationBannerListener {
void onDismissScreen(MediationBannerAdapter p0);
}
public interface MediationInterstitialListener {
void onDismissScreen(MediationInterstitialAdapter p0);
}
Bu, tasarım gereğidir, böylece olay bağımsız değişken türlerinde uzun adlardan kaçınılır. Bu çakışmaları önlemek için bir miktar meta veri dönüştürmesi gerekir.
Dönüştürmeleri düzenle\Metadata.xml ve arabirimlerden birinde (veya arabirim yönteminde) bir argsType öznitelik ekleyin:
<attr path="/api/package[@name='com.google.ads.mediation']/
interface[@name='MediationBannerListener']/method[@name='onDismissScreen']"
name="argsType">BannerDismissScreenEventArgs</attr>
<attr path="/api/package[@name='com.google.ads.mediation']/
interface[@name='MediationInterstitialListener']/method[@name='onDismissScreen']"
name="argsType">IntersitionalDismissScreenEventArgs</attr>
<attr path="/api/package[@name='android.content']/
interface[@name='DialogInterface.OnClickListener']"
name="argsType">DialogClickEventArgs</attr>
Sorun: Sınıf arabirim yöntemini uygulamıyor
Oluşturulan bir sınıfın, oluşturulan sınıfın uyguladığı bir arabirim için gerekli olan bir yöntemi uygulamadığını belirten bir hata iletisi oluşturulur. Ancak, oluşturulan koda baktığınızda yönteminin uygulandığını görebilirsiniz.
Hatanın bir örneği aşağıda verilmiştir:
obj\Debug\generated\src\Oauth.Signpost.Basic.HttpURLConnectionRequestAdapter.cs(8,23):
error CS0738: 'Oauth.Signpost.Basic.HttpURLConnectionRequestAdapter' does not
implement interface member 'Oauth.Signpost.Http.IHttpRequest.Unwrap()'.
'Oauth.Signpost.Basic.HttpURLConnectionRequestAdapter.Unwrap()' cannot implement
'Oauth.Signpost.Http.IHttpRequest.Unwrap()' because it does not have the matching
return type of 'Java.Lang.Object'
Olası nedenler:
Bu, java yöntemlerinin birlikte değişken dönüş türleriyle bağlanmasıyla oluşan bir sorundur. Bu örnekte Oauth.Signpost.Http.IHttpRequest.UnWrap() yönteminin Java.Lang.Object döndürmesi gerekmektedir. Ancak Oauth.Signpost.Basic.HttpURLConnectionRequestAdapter.UnWrap() yönteminin dönüş türü HttpURLConnection. Bu sorunu düzeltmenin iki yolu vardır:
HttpURLConnectionRequestAdapteriçin bir kısmi sınıf bildirimi ekleyin veIHttpRequest.Unwrap()'i açık bir şekilde uygulayın.namespace Oauth.Signpost.Basic { partial class HttpURLConnectionRequestAdapter { Java.Lang.Object OauthSignpost.Http.IHttpRequest.Unwrap() { return Unwrap(); } } }Oluşturulan C# kodundan kovaryansı kaldırın. Bu, oluşturulan C# kodunun dönüş türüne sahip olmasına neden olacak
Java.Lang.Objectaşağıdaki dönüşümü eklemeyi içerir:<attr path="/api/package[@name='oauth.signpost.basic']/class[@name='HttpURLConnectionRequestAdapter']/method[@name='unwrap']" name="managedReturn">Java.Lang.Object </attr>
Sorun: İç sınıflarda / özelliklerde ad çakışmaları
Devralınan nesnelerde çelişen görünürlük.
Java'da, türetilmiş bir sınıfın üst sınıfıyla aynı görünürlüğe sahip olması gerekmez. Java bunu sizin için düzeltir. C# dilinde bu açık olmalıdır, bu nedenle hiyerarşideki tüm sınıfların uygun görünürlüğe sahip olduğundan emin olmanız gerekir. Aşağıdaki örnekte, com.evernote.android.job Java paketi adının Evernote.AndroidJob olarak nasıl değiştirileceği gösterilmektedir.
<!-- Change the visibility of a class -->
<attr path="/api/package[@name='namespace']/class[@name='ClassName']" name="visibility">public</attr>
<!-- Change the visibility of a method -->
<attr path="/api/package[@name='namespace']/class[@name='ClassName']/method[@name='MethodName']" name="visibility">public</attr>
Sorun: Bağlama için gereken .so kitaplığı yüklenmiyor
Bazı bağlama projeleri bir .so kitaplığındaki işlevselliğe de bağlı olabilir. Android için .NET'in .so kitaplığını otomatik olarak yüklememesi mümkündür. Java kodu sarıldığında çalıştırıldığında, Android için .NET JNI çağrısını yapamaz ve hata mesajı java.lang.UnsatisfiedLinkError: Native yöntemi bulunamadı: uygulama logcat çıktısında görünür.
Bu sorunu düzeltmek için, .so kütüphanesini Java.Lang.JavaSystem.LoadLibrary çağrısıyla manuel olarak yükleyin. Örneğin, Bir Android için .NET projesinin embeddedNativeLibrary derleme eylemiyle bağlama projesine dahil libpocketsphinx_jni.so paylaşılan kitaplığı olduğunu varsayarsak, aşağıdaki kod parçacığı (paylaşılan kitaplığı kullanmadan önce yürütülür) .so kitaplığını yükler:
Java.Lang.JavaSystem.LoadLibrary("pocketsphinx_jni");