Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Привязка библиотеки Android (файл AAR или JAR) редко проходит просто. Обычно требуются дополнительные усилия для устранения проблем, возникающих из-за различий между Java и .NET. Эти проблемы не позволят .NET для Android подключить библиотеку Android и будут представлены в виде сообщений об ошибках в журнале сборки. В этом руководстве представлены некоторые советы по устранению неполадок, перечислены самые типичные проблемы и сценарии, а также предложены возможные решения для успешной привязки библиотеки Android.
При привязке существующей библиотеки Android необходимо учитывать следующие моменты:
Внешние зависимости библиотеки — все зависимости Java, необходимые библиотеке Android, должны быть включены в проект .NET для Android через пакет NuGet или в виде AndroidLibrary.
Уровень API Android, предназначенный для библиотеки Android, — невозможно "понижение" уровня API Android; убедитесь, что проект привязки .NET для Android предназначен для того же уровня API (или выше), что и библиотека Android.
Совет
Вики-сайт репозитория инструментов привязки GitHub является полезным ресурсом и содержит дополнительные сведения по устранению неполадок, которые могут помочь в отдельных случаях.
Первым шагом в устранении неполадок с привязкой библиотеки .NET для Android является включение диагностического вывода MSBuild. После включения диагностических выходных данных перестройте проект привязки .NET для Android и изучите журнал сборки, чтобы найти подсказки о причинах проблемы.
Она также может оказаться полезной для декомпилирования библиотеки Android и изучения типов и методов, которые пытается привязать .NET для Android. Более подробно этот процесс рассматривается далее в этом руководстве.
Декомпилирование библиотеки Android
Изучение классов и методов Java может дать ценную информацию, которая поможет привязать библиотеку. Служебная программа с графическим интерфейсом JD-GUI умеет отображать исходный код Java из файлов CLASS, включенных в пакет JAR.
Чтобы декомпилировать библиотеку Android, откройте файл JAR в декомпиляторе Java. Если библиотека является файлом AAR, исходный код Java будет находиться в записи classes.jar архивного файла. На снимке экрана ниже демонстрируется применение JD-GUI для анализа JAR-файла Picasso.
Декомпилировав файл библиотеки Android, изучите ее исходный код. Особое внимание следует обращать на следующие признаки:
К классам, имеющим характеристики запутывания , относятся характеристики скрытых классов:
- имя класса содержит символ $, например a$.class;
- имя класса полностью состоит из строчных букв, например a.class.
importуказания для библиотек без ссылок — идентифицируйте библиотеку без ссылок и добавьте зависимости в проект привязки .NET для Android с использованием подходящей привязки через NuGet или с Build ActionAndroidLibrary.
Примечание.
Декомпиляция библиотеки Java может быть запрещена или юридически ограничена в соответствии с местным законодательством или условиями лицензии, по которой эта библиотека была опубликована. Если потребуется, обратитесь за консультацией к профессиональным юристам перед декомпиляцией библиотеки Java и изучением ее исходного кода.
Проверьте api.xml
В рамках создания проекта привязки .NET для Android сгенерирует файл obj/Debug/api.xml:
Этот файл содержит список всех API Java, которые .NET для Android пытается привязать. Содержимое этого файла может помочь найти недостающие типы или методы, а также повторные привязки. Хотя изучение этого файла может быть сложным и долгим, оно может дать полезные подсказки о причинах проблем с привязкой. Например, из api.xml можно узнать, что свойство возвращает недопустимый тип или существуют два типа с одним управляемым именем.
Известные проблемы
Этот раздел содержит список самых распространенных сообщений об ошибках и симптомов, которые могут проявляться при попытке привязать библиотеку Android.
Проблема: отсутствуют типы C# в созданных выходных данных.
Файл DLL привязки создается, но в нем отсутствуют некоторые типы Java, или созданный исходный код C# не компилируется из-за ошибки с сообщением об отсутствии типов.
Возможные причины:
Эта ошибка может быть связана с любой из перечисленных ниже причин.
Привязываемая библиотека может ссылаться на другую библиотеку Java. Если открытый API для привязываемой библиотеки использует типы из второй библиотеки, вам необходимо создать ссылку на управляемую привязку и для второй библиотеки.
Java позволяет наследовать публичный класс от непубличного класса, но в .NET это не поддерживается. Поскольку генератор привязки не создает привязки для закрытых классов, производные классы не могут быть сформированы правильно. Чтобы устранить эту проблему, удалите запись метаданных для производных классов из Metadata.xml с помощью remove-node или исправьте метаданные так, чтобы закрытый класс стал открытым. Несмотря на то, что последнее решение правильно создаст привязку и компиляция исходного кода C# пройдет успешно, не следует использовать закрытый класс.
Например:
<attr path="/api/package[@name='com.some.package']/class[@name='SomeClass']" name="visibility">public</attr>Средства, которые скрывают библиотеки Java, могут препятствовать генератору привязок .NET для Android и его возможности создавать классы-оболочки C#. В следующем фрагменте кода показано, как изменить Metadata.xml, чтобы убрать обфускацию имени класса.
<attr path="/api/package[@name='{package_name}']/class[@name='{name}']" name="obfuscated">false</attr>
Проблема: созданный источник C# не выполняет сборку из-за несоответствия типа параметров
Созданный исходный код C# не компилируется. Типы параметров переопределенного метода не совпадают.
Возможные причины:
.NET для Android включает в себя различные поля Java, которые сопоставляются с перечислениями в привязках C#. Это может приводить к несовместимости типов в созданных привязках. Чтобы устранить такую проблему, нужно исправить сигнатуры методов, созданные генератором привязок, и перейти на использование перечислений. Дополнительные сведения см. в разделе "Создание перечислений".
Проблема: дублирующиеся кастомные типы EventArgs
Сборка завершается ошибкой из-за дублирования пользовательских типов EventArgs. Ошибка будет выглядеть примерно так:
error CS0102: The type `Com.Google.Ads.Mediation.DismissScreenEventArgs' already contains a definition for `p0'
Возможные причины:
Это связано с конфликтом между типами событий, которые поступают от нескольких типов интерфейса «слушатель», имеющих методы с одинаковыми именами. Например, для двух представленных в примере ниже интерфейсов Java генератор создаст DismissScreenEventArgs как для MediationBannerListener, так и для MediationInterstitialListener, что приведет к ошибке.
// Java:
public interface MediationBannerListener {
void onDismissScreen(MediationBannerAdapter p0);
}
public interface MediationInterstitialListener {
void onDismissScreen(MediationInterstitialAdapter p0);
}
Это ожидаемое поведение, которое позволяет избежать слишком длинных имен для типов аргументов событий. Чтобы избежать таких конфликтов, потребуется преобразовать метаданные. Откройте файл Transforms\Metadata.xml и добавьте атрибут argsType для любого из интерфейсов (или в метод интерфейса).
<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>
Проблема. Класс не реализует метод интерфейса
Появляется ошибка с сообщением о том, что созданный класс не реализует метод, который является обязательным для реализуемого этим классом интерфейса. Однако, посмотрев на созданный код, вы можете видеть, что метод реализован.
Вот пример такой ошибки:
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'
Возможные причины:
Такая проблема возникает при привязке методов Java с ковариантными возвращаемыми типами. В нашем примере метод Oauth.Signpost.Http.IHttpRequest.UnWrap() должен возвращать Java.Lang.Object. Но метод Oauth.Signpost.Basic.HttpURLConnectionRequestAdapter.UnWrap() имеет тип возвращаемого значения HttpURLConnection. Устранить эту проблему можно двумя способами:
Объявите частичный класс для
HttpURLConnectionRequestAdapterи явно реализуйтеIHttpRequest.Unwrap().namespace Oauth.Signpost.Basic { partial class HttpURLConnectionRequestAdapter { Java.Lang.Object OauthSignpost.Http.IHttpRequest.Unwrap() { return Unwrap(); } } }Удалите ковариантность из созданного кода C#. Для этого нужно добавить следующее преобразование в файл Transforms\Metadata.xml, чтобы созданный код C# мог иметь тип возвращаемого значения
Java.Lang.Object.<attr path="/api/package[@name='oauth.signpost.basic']/class[@name='HttpURLConnectionRequestAdapter']/method[@name='unwrap']" name="managedReturn">Java.Lang.Object </attr>
Проблема: столкновения имен во внутренних классах и свойствах
Конфликт видимости у наследуемых объектов.
В Java производный класс не обязан иметь ту же область видимости, что и родительский класс. Java автоматически исправляет это. Но в C# такие объявления должны быть явными, поэтому вам нужно обеспечить правильную область видимости для всех классов в иерархии. В следующем примере показано, как изменить имя пакета Java с com.evernote.android.job на 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 , требуемая привязкой, не загружается
Некоторые проекты с привязкой могут также зависеть от функциональности в библиотеке .so. Возможно, что .NET для Android не будет автоматически загружать библиотеку .so . При выполнении упакованного кода Java .NET для Android не сможет выполнить вызов JNI и сообщение об ошибке java.lang.UnsatisfiedLinkError: нативный метод не найден: появится в выходе приложения.
Чтобы исправить это, вручную загрузите нужную библиотеку SO с помощью вызова Java.Lang.JavaSystem.LoadLibrary. Например, если проект .NET для Android имеет общую библиотеку libpocketsphinx_jni.so, включенную в проект привязки с параметром сборки EmbeddedNativeLibrary, следующий фрагмент кода (выполнен перед использованием общей библиотеки) загружает библиотеку .so :
Java.Lang.JavaSystem.LoadLibrary("pocketsphinx_jni");