Устранение неполадок с привязкамиTroubleshooting Bindings

В этой статье перечислены несколько распространенных ошибок, которые могут возникнуть при создании привязки, а также возможные причины и предлагаемые способы их устранения.This article summarizes serveral common errors that may occur when generating bindings, along with possible causes and suggested ways to resolve them.

ОбзорOverview

Привязка библиотеки Android ( .aar или .jar) файл редко является простой задачей; она обычно требует дополнительных усилий по уменьшению проблем, возникающих из-за различий между Java и .NET.Binding an Android library (an .aar or a .jar) file is seldom a straightforward affair; it usually requires additional effort to mitigate issues that result from the differences between Java and .NET. Эти проблемы запрещает привязка библиотеки Android Xamarin.Android и имитируют сообщения об ошибках в журнале сборки.These issues will prevent Xamarin.Android from binding the Android library and present themselves as error messages in the build log. В этом руководстве будет предоставить некоторые советы по устранению неполадок, перечислены некоторые из наиболее распространенных проблем и сценарии и могут оказаться полезными для успешной привязки библиотеки Android.This guide will provide some tips for troubleshooting the issues, list some of the more common problems/scenarios, and provide possible solutions to successfully binding the Android library.

Во время привязки существующей библиотеки Android, бывает необходимо помнить следующее:When binding an existing Android library, it is necessary to keep in mind the following points:

  • Внешние зависимости для библиотеки – Any Java зависимости, необходимые для библиотеки Android должен быть включен в проект Xamarin.Android, как ReferenceJar или как EmbeddedReferenceJar.The external dependencies for the library – Any Java dependencies required by the Android library must be included in the Xamarin.Android project as a ReferenceJar or as an EmbeddedReferenceJar.

  • Уровень Android API, что библиотеки Android ориентирован – он уже не сможете «понизить» уровень Android API; убедитесь, что проект привязки Xamarin.Android предназначен тот же API, уровень (или выше) как библиотеки Android.The Android API level that the Android library is targetting – It is not possible to "downgrade" the Android API level; ensure that the Xamarin.Android binding project is targeting the same API level (or higher) as the Android library.

  • Версия Android JDK, который был использован для пакета библиотеки Android – ошибок привязки может возникать, если библиотеки Android создана с помощью другой версии JDK, отличного от того, используется для Xamarin.Android.The version of the Android JDK that was used to package the Android library – Binding errors may occur if the Android library was built with a different version of JDK than the one in use by Xamarin.Android. Если это возможно выполните повторную компиляцию библиотеки Android, используя ту же версию JDK, который используется для установки Xamarin.Android.If possible, recompile the Android library using the same version of the JDK that is used by your installation of Xamarin.Android.

Первым шагом устранения неполадок с привязка библиотеки Xamarin.Android является возможность вывод диагностики MSBuild.The first step to troubleshooting issues with binding a Xamarin.Android library is to enable diagnostic MSBuild output. После включения выходных данных диагностики, перестройте проект Xamarin.Android привязки и проверьте журнал построения, чтобы найти сведения о том, что причиной проблемы.After enabling the diagnostic output, rebuild the Xamarin.Android binding project and examine the build log to locate clues about what the cause of problem is.

Он также могут оказаться полезными декомпилировать библиотеки Android и изучить типы и методы, которые пытается привязать Xamarin.Android.It can also prove helpful to decompile the Android library and examine the types and methods that Xamarin.Android is trying to bind. Это рассматривается более подробно далее в этом руководстве.This is covered in more detail later on in this guide.

Восстановление библиотеку для AndroidDecompiling an Android Library

Проверять классы и методы классов Java может предоставить ценную информацию, которая будет полезна при привязке библиотеки.Inspecting the classes and methods of the Java classes can provide valuable information that will assist in binding a library. Графического интерфейса JD — это графическая программа, которая может отображать исходный код Java из класс файлы, содержащиеся в JAR-ФАЙЛ.JD-GUI is a graphical utility that can display Java source code from the CLASS files contained in a JAR. Он может выполняться как никакое отдельное приложение или как подключаемый модуль IntelliJ или Eclipse.It can be run as a stand alone application or as a plug-in for IntelliJ or Eclipse.

Чтобы декомпилировать открытую библиотеку Android . JAR- файл с декомпилятор Java.To decompile an Android library open the .JAR file with the Java decompiler. Если библиотека . AAR файл, это необходимо, чтобы извлечь файл classes.jar из файла архива.If the library is an .AAR file, it is necessary to extract the file classes.jar from the archive file. Ниже приведен пример снимка экрана с помощью графического интерфейса JD для анализа Пикассо JAR:The following is a sample screenshot of using JD-GUI to analyze the Picasso JAR:

Использование Java декомпилятор для анализа Пикассо 2.5.2.jar

Как только декомпилированным библиотеки Android, изучите исходный код.Once you have decompiled the Android library, examine the source code. Вообще говоря поиск:Generally speaking, look for :

  • Классы, которые имеют характеристики запутывания – характеристики скрытый классов включают:Classes that have characteristics of obfuscation – Characteristics of obfuscated classes include:

    • Имя класса включает $, т. е. $.classThe class name includes a $, i.e. a$.class
    • Имя класса полностью включает в себя символы в нижнем регистре, т. е. a.classThe class name is entirely compromised of lower case characters, i.e. a.class
  • import инструкции для библиотек, на которые нет ссылок – идентификации без ссылки библиотеки и добавить эти зависимости в проект Xamarin.Android привязки с действие при построении из ReferenceJar или EmbedddedReferenceJar.import statements for unreferenced libraries – Identify the unreferenced library and add those dependencies to the Xamarin.Android binding project with a Build Action of ReferenceJar or EmbedddedReferenceJar.

Примечание

Декомпиляции библиотеки Java может быть запрещено или юридические ограничения на основе местного законодательства или лицензии, под которой была опубликована библиотеке Java.Decompiling a Java library may be prohibited or subject to legal restrictions based on local laws or the license under which the Java library was published. При необходимости выполнить прикрепление в службах юридические professional перед попыткой декомпилировать библиотеки Java и ознакомиться с исходным кодом.If necessary, enlist the services of a legal professional before attempting to decompile a Java library and inspect the source code.

Изучите API. XMLInspect API.XML

Как часть сборки проекта привязки, Xamarin.Android создаст имя файла XML obj/Debug/api.xml:As a part of building a binding project, Xamarin.Android will generate an XML file name obj/Debug/api.xml:

Созданный api.xml под obj/Debug

Этот файл предоставляет список всех API-интерфейсы Java, что Xamarin.Android пытается привязки.This file provides a list of all the Java APIs that Xamarin.Android is trying bind. Содержимое этого файла может помочь выявить любые отсутствующие типы или методы, повторяющаяся привязка.The contents of this file can help identify any missing types or methods, duplicate binding. Несмотря на то, что проверки этого файла сил и времени, может предоставлять для подсказки, на что может быть причиной возникновения проблемы любой привязки.Although inspection of this file is tedious and time consuming, it can provide for clues on what might be causing any binding problems. Например api.xml может показать, что свойство возвращает неподходящего типа, или что имеются два типов данной общей папки с тем же именем управляемого.For example, api.xml might reveal that a property is returning an inappropriate type, or that there are two types that share the same managed name.

Известные проблемыKnown Issues

В этом разделе будут перечислены некоторые распространенные сообщения об ошибках или симптомы, Мой при попытке привязать библиотеку Android.This section will list some of the common error messages or symptoms that my occur when trying to bind an Android library.

Проблема: Несовпадение версий JavaProblem: Java Version Mismatch

Иногда типы не будут созданы или непредвиденных сбоев может возникать при использовании либо новее или старше версию по сравнению с библиотеки был скомпилирован с помощью Java.Sometimes types will not be generated or unexpected crashes may occur because you are using either a newer or older version of Java compared to what the library was compiled with. Выполните повторную компиляцию библиотеки Android с помощью той же версии JDK, использующего проект Xamarin.Android.Recompile the Android library with the same version of the JDK that your Xamarin.Android project is using.

Проблема: Необходим хотя бы одна библиотека JavaProblem: At least one Java library is required

При возникновении ошибки «хотя бы одна библиотека Java является обязательным,», даже если. JAR-ФАЙЛ был добавлен.You receive the error "at least one Java library is required," even though a .JAR has been added.

Возможные причины:Possible Causes:

Убедитесь, что действие построения присваивается EmbeddedJar.Make sure the build action is set to EmbeddedJar. Так как существует несколько действий сборки для. JAR-файлы (такие как InputJar, EmbeddedJar, ReferenceJar и EmbeddedReferenceJar), генератор привязки не может автоматически угадать какой из них следует использовать по умолчанию.Since there are multiple build actions for .JAR files (such as InputJar, EmbeddedJar, ReferenceJar and EmbeddedReferenceJar), the binding generator cannot automatically guess which one to use by default. Дополнительные сведения о действиях при сборке, см. в разделе действия построения.For more information about build actions, see Build Actions.

Проблема: Привязка средства не удается загрузить. Библиотеки JAR-файловProblem: Binding tools cannot load the .JAR library

Не удается загрузить библиотеку генератор привязки. Библиотеки JAR-файлов.The binding library generator fails to load the .JAR library.

Возможные причиныPossible Causes

Некоторые. Не удалось загрузить библиотеки JAR, использующих запутывания кода (с помощью инструментов, как Proguard) с помощью инструментов Java.Some .JAR libraries that use code obfuscation (via tools such as Proguard) cannot be loaded by the Java tools. Поскольку наше средство делает использование отражения Java и байт-кода ASM, проектирование библиотеки, эти зависимые средства может отклонить скрытый библиотеки, хотя средства среды выполнения Android может передать.Since our tool makes use of Java reflection and the ASM byte code engineering library, those dependent tools may reject the obfuscated libraries while Android runtime tools may pass. Решением этой проблемы является наличии привязку этих библиотек, вместо того чтобы использовать генератор привязки.The workaround for this is to hand-bind these libraries instead of using the binding generator.

Проблема: Отсутствует C# типов в выходные данные.Problem: Missing C# types in generated output.

Привязка .dll сборки, но пропускает некоторые типы Java или созданный C# источника не выполняет сборку из-за сообщение о том, существует типа отсутствует.The binding .dll builds but misses some Java types, or the generated C# source does not build due to an error stating there are missing types.

Возможные причины:Possible Causes:

Эта ошибка может возникать несколько причин, как показано ниже:This error may occur due to several reasons as listed below:

  • Библиотеки привязки может ссылаться на второй библиотеки Java.The library being bound may reference a second Java library. Если открытый API для привязанного библиотека использует типы из второй библиотеки, управляемом привязку для второй библиотеки, а также необходимо ссылаться.If the public API for the bound library uses types from the second library, you must reference a managed binding for the second library as well.

  • Вполне возможно, что из-за отражения Java, аналогичную причина Ошибка загрузки библиотеки выше, вызывает непредвиденные загрузку метаданных внедренном в библиотеку.It is possible that a library was injected due to Java reflection, similar to the reason for the library load error above, causing the unexpected loading of metadata. Xamarin.Android инструментарий не способен разрешать в настоящее время такой ситуации.Xamarin.Android's tooling cannot currently resolve this situation. В таком случае библиотеки необходимо вручную привязать.In such a case, the library must be manually bound.

  • Произошла ошибка в среде выполнения .NET 4.0, которая не удалось загрузить сборки, у него должно быть.There was a bug in .NET 4.0 runtime that failed to load assemblies when it should have. Эта проблема будет исправлена в среде выполнения .NET 4.5.This issue has been fixed in the .NET 4.5 runtime.

  • Java позволяет открытый класс производным от класса, не являющиеся открытыми, но это не поддерживается в .NET.Java allows deriving a public class from non-public class, but this is unsupported in .NET. Так как генератор привязки не создает привязки для закрытые классы, производные классы, такие, как они не могут быть созданы правильно.Since the binding generator does not generate bindings for non-public classes, derived classes such as these cannot be generated correctly. Чтобы устранить эту проблему, удалите запись метаданных для производных классов с помощью функции remove узлов в Metadata.xml, или исправьте метаданные, которые делает класс закрытые открытый.To fix this, either remove the metadata entry for those derived classes using the remove-node in Metadata.xml, or fix the metadata that is making the non-public class public. Несмотря на то, что последнее решение будет создать привязку, чтобы C# построит источника, не следует использовать класс не являющиеся открытыми.Although the latter solution will create the binding so that the C# source will build, the non-public class should not be used.

    Пример:For example:

    <attr path="/api/package[@name='com.some.package']/class[@name='SomeClass']"
        name="visibility">public</attr>
    
  • Средства, закрывающие библиотеки Java может помешать генератор привязки Xamarin.Android и его способность создавать C# классы-оболочки.Tools that obfuscate Java libraries may interfere with the Xamarin.Android Binding Generator and its ability to generate C# wrapper classes. В следующем фрагменте показано, как обновить Metadata.xml для unobfuscate имя класса:The following snippet shows how to update Metadata.xml to unobfuscate a class name:

    <attr path="/api/package[@name='{package_name}']/class[@name='{name}']"
        name="obfuscated">false</attr>
    

Проблема: Созданный C# источника не выполняет сборку из-за несоответствия типа параметраProblem: Generated C# source does not build due to parameter type mismatch

Созданный C# источника не выполняет сборку.The generated C# source does not build. Переопределить параметр метода, которые не совпадают типы.Overridden method's parameter types do not match.

Возможные причины:Possible Causes:

Xamarin.Android включает в себя различные поля Java, которые сопоставляются с перечислений в C# привязки.Xamarin.Android includes a variety of Java fields that are mapped to enums in the C# bindings. Это может привести к несовместимости по типам в созданный привязках.These can cause type incompatibilities in the generated bindings. Чтобы устранить эту проблему, подписи методов, созданные из генератора, привязки должны быть изменены для использования перечислений.To resolve this, the method signatures created from the binding generator need to be modified to use the enums. Дополнительные imformation см. в разделе исправление перечисления.For more imformation, please see Correcting Enums.

Проблема: NoClassDefFoundError в упаковкеProblem: NoClassDefFoundError in packaging

java.lang.NoClassDefFoundError вызывается на этапе упаковки.java.lang.NoClassDefFoundError is thrown in the packaging step.

Возможные причины:Possible Causes:

Наиболее вероятная причина этой ошибки является обязательным библиотеки Java необходимо добавить в проект приложения (.csproj).The most likely reason for this error is that a mandatory Java library needs to be added to the application project (.csproj). . JAR-файлы, не разрешаются автоматически..JAR files are not automatically resolved. Привязка библиотеки Java не всегда создается для пользовательской сборкой, не существует в целевом устройстве или эмуляторе (например Google Maps maps.jar).A Java library binding is not always generated against a user assembly that does not exist in the target device or emulator (such as Google Maps maps.jar). Это не так, для поддержки проекта библиотеки Android, как у библиотеки. JAR-ФАЙЛ внедряются в библиотеки dll.This is not the case for Android Library project support, as the library .JAR is embedded in the library dll. Пример: Ошибка 4288For example: Bug 4288

Проблема: Повторяющиеся пользовательских типов EventArgsProblem: Duplicate custom EventArgs types

Сборка завершается сбоем из-за повторяющихся пользовательских типов EventArgs.Build fails due to duplicate custom EventArgs types. Ошибка следующим образом:An error like this occurs:

error CS0102: The type `Com.Google.Ads.Mediation.DismissScreenEventArgs' already contains a definition for `p0'

Возможные причины:Possible Causes:

Это из-за некоторых конфликта между типами событий, полученных из более чем один тип интерфейса «прослушиватель», который использует методы с одинаковыми именами.This is because there is some conflict between event types that come from more than one interface "listener" type that shares methods having identical names. Например, если имеются два интерфейса Java, как показано в следующем примере, генератор создает DismissScreenEventArgs для обоих MediationBannerListener и MediationInterstitialListener, полученный в ошибке.For example, if there are two Java interfaces as seen in the example below, the generator creates DismissScreenEventArgs for both MediationBannerListener and MediationInterstitialListener, resulting in the error.

// Java:
public interface MediationBannerListener {
    void onDismissScreen(MediationBannerAdapter p0);
}
public interface MediationInterstitialListener {
    void onDismissScreen(MediationInterstitialAdapter p0);
}

Это сделано намеренно, чтобы длинные имена на типы аргументов событий, удается избежать.This is by design so that lengthy names on event argument types are avoided. Чтобы избежать таких конфликтов, некоторые метаданные преобразования не требуется.To avoid these conflicts, some metadata transformation is required. Изменить Transforms\Metadata.xml и добавьте argsType атрибут на одном из интерфейсов (или метода интерфейса):Edit Transforms\Metadata.xml and add an argsType attribute on either of the interfaces (or on the interface method):

<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>

Проблема: Класс не реализует метод интерфейсаProblem: Class does not implement interface method

Сообщение об ошибке создается, указывающее, что созданный класс не реализует метод, который необходим для интерфейса, который реализует созданный класс.An error message is produced indicating that a generated class does not implement a method that is required for an interface which the generated class implements. Тем не менее изучение созданного кода, можно увидеть, что метод реализуется.However, looking at the generated code, you can see that the method is implemented.

Вот пример ошибки:Here is an example of the error:

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'

Возможные причины:Possible Causes:

Это проблема, которая происходит при использовании привязки методов Java с помощью ковариантные типы возвращаемого значения.This is a problem that occurs with binding Java methods with covariant return types. В этом примере метод Oauth.Signpost.Http.IHttpRequest.UnWrap() должно возвращать Java.Lang.Object.In this example, the method Oauth.Signpost.Http.IHttpRequest.UnWrap() needs to return Java.Lang.Object. Тем не менее метод Oauth.Signpost.Basic.HttpURLConnectionRequestAdapter.UnWrap() имеет тип возвращаемого значения HttpURLConnection.However, the method Oauth.Signpost.Basic.HttpURLConnectionRequestAdapter.UnWrap() has a return type of HttpURLConnection. Чтобы устранить эту проблему двумя способами:There are two ways to fix this issue:

  • Добавьте объявление разделяемого класса для HttpURLConnectionRequestAdapter и явно реализуйте IHttpRequest.Unwrap():Add a partial class declaration for HttpURLConnectionRequestAdapter and explicitly implement IHttpRequest.Unwrap():

    namespace Oauth.Signpost.Basic {
        partial class HttpURLConnectionRequestAdapter {
            Java.Lang.Object OauthSignpost.Http.IHttpRequest.Unwrap() {
                return Unwrap();
            }
        }
    }
    
  • Удалить ковариацию из созданного C# кода.Remove the covariance from the generated C# code. Этот процесс включает добавление следующее преобразование для Transforms\Metadata.xml вызывающее созданный C# коду иметь тип возвращаемого значения Java.Lang.Object:This involves adding the following transform to Transforms\Metadata.xml which will cause the generated C# code to have a return type of Java.Lang.Object:

    <attr
        path="/api/package[@name='oauth.signpost.basic']/class[@name='HttpURLConnectionRequestAdapter']/method[@name='unwrap']"
        name="managedReturn">Java.Lang.Object
    </attr>
    

Проблема: Назовите конфликтов на внутренние классы и свойстваProblem: Name Collisions on Inner Classes / Properties

Конфликтующие включена видимость унаследованных объектов.Conflicting visibility on inherited objects.

В Java это не обязательно наличие ту же видимость, что родительского в производном классе.In Java, it's not required that a derived class have the same visibility as its parent. Java будет просто исправить это для вас.Java will just fix that for you. В C#, должна быть явными, поэтому убедитесь, что все классы в иерархии имеют соответствующие видимость.In C#, that has to be explicit, so you need to make sure all classes in the hierarchy have the appropriate visibility. Приведенный ниже показано, как изменить имя пакета Java из com.evernote.android.job для Evernote.AndroidJob:The following example shows how to change a Java package name from com.evernote.android.job to Evernote.AndroidJob:

<!-- 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>

Проблема: Объект .so — библиотеки, необходимые в привязке не удалось загрузитьProblem: A .so Library Required by the Binding is Not Loading

Некоторые проекты привязки может также зависеть от функциональные возможности .so библиотеки.Some binding projects may also depend on functionality in a .so library. Возможно, что Xamarin.Android не будут загружаться автоматически .so библиотеки.It is possible that Xamarin.Android will not automatically load the .so library. При выполнении упакованного кода Java для вызова JNI и сообщение об ошибке не удастся Xamarin.Android java.lang.UnsatisfiedLinkError: Собственный метод, не найден: будет отображаться в logcat out для приложения.When the wrapped Java code executes, Xamarin.Android will fail to make the JNI call and the error message java.lang.UnsatisfiedLinkError: Native method not found: will appear in the logcat out for the application.

Способ устранения этой проблемы является вручную загрузить .so библиотеки с помощью вызова Java.Lang.JavaSystem.LoadLibrary.The fix for this is to manually load the .so library with a call to Java.Lang.JavaSystem.LoadLibrary. Например при условии, что проект Xamarin.Android общая библиотека libpocketsphinx_jni.so включен в проект привязки с действием сборки EmbeddedNativeLibrary, следующий фрагмент кода (выполняется перед использованием общей библиотеки) будет загружать .so библиотеки:For example assuming that a Xamarin.Android project has shared library libpocketsphinx_jni.so included in the binding project with a build action of EmbeddedNativeLibrary, the following snippet (executed before using the shared library) will load the .so library:

Java.Lang.JavaSystem.LoadLibrary("pocketsphinx_jni");

СводкаSummary

В этой статье перечислены распространенные проблемы, связанные с привязками, Java и описаны способы их устранения.In this article, we listed common troubleshooting issues associated with Java Bindings and explained how to resolve them.