jar-привязка ActionBarSherlock для Mono для Android

Мне нравится привязывать jar-библиотеку ActionBarSherlock к моему проекту Mono For Android. Я уважаю эту документацию: http://docs.xamarin.com/android/tutorials/Binding_a_Java_Library_%28.jar%29

Я успешно связал android-support-v4.jar, который необходим ActionBarSherlock. Но когда я пытаюсь скомпилировать actionbarsherlock.jar, появляется следующее сообщение об ошибке:

Target ResolveLibraryProjects:
    Skipping target "ResolveLibraryProjects" because it has no inputs.
    Target _ResolveMonoAndroidSdks:
        MonoAndroid Tools: C:\Program Files (x86)\MSBuild\Novell\
        MonoAndroid Framework: C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\MonoAndroid\v2.2\;C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\MonoAndroid\v1.0\
        Android SDK: C:\Program Files (x86)\Android\android-sdk\
        Java SDK: C:\Program Files (x86)\Java\jdk1.6.0_31\
    Target ExportJarToXml:
          SourceJars:
            Jars\actionbarsherlock.jar
          ReferenceJars:
            Jars\android-support-v4.jar
        C:\Program Files (x86)\Java\jdk1.6.0_31\bin\java.exe -jar "C:\Program Files (x86)\MSBuild\Novell\jar2xml.jar" --jar=C:\Users\assrock\Documents\JavaBind\JavaBind\Jars\actionbarsherlock.jar --ref="C:\Program Files (x86)\Android\android-sdk\platforms\android-8\android.jar" --out=C:\Users\assrock\Documents\JavaBind\JavaBind\obj\Release\api.xml --ref=C:\Users\assrock\Documents\JavaBind\JavaBind\Jars\android-support-v4.jar 
        Couldn't load class com/actionbarsherlock/internal/ActionBarSherlockNative$ActionModeCallbackWrapper
        Couldn't load class com/actionbarsherlock/internal/app/ActionBarWrapper$TabWrapper
        Couldn't load class com/actionbarsherlock/internal/app/ActionBarWrapper
        Couldn't load class com/actionbarsherlock/internal/view/ActionProviderWrapper
        Couldn't load class com/actionbarsherlock/internal/view/menu/MenuItemWrapper$1
        Exception in thread "main" java.lang.NoClassDefFoundError: com/actionbarsherlock/R
            at java.lang.Class.getDeclaringClass(Native Method)
            at jar2xml.JavaClass.getConstructorParameterOffset(JavaClass.java:149)
            at jar2xml.JavaClass.appendCtor(JavaClass.java:138)
            at jar2xml.JavaClass.appendToDocument(JavaClass.java:462)
            at jar2xml.JavaPackage.appendToDocument(JavaPackage.java:66)
            at jar2xml.Start.main(Start.java:157)
        Caused by: java.lang.ClassNotFoundException: com.actionbarsherlock.R
            at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
            at java.security.AccessController.doPrivileged(Native Method)
            at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
            ... 6 more
C:\Program Files (x86)\MSBuild\Novell\Xamarin.Android.Bindings.targets(170,5): error MSB6006: "java.exe" exited with code 1.
    Task "JarToXml" execution -- FAILED
    Done building target "ExportJarToXml" in project "C:\Users\assrock\Documents\JavaBind\JavaBind\JavaBind.csproj".-- FAILED
Done building project "C:\Users\assrock\Documents\JavaBind\JavaBind\JavaBind.csproj".-- FAILED
Build FAILED.
Warnings:
C:\Program Files (x86)\MSBuild\Novell\Xamarin.Android.Bindings.targets(40,11): warning MSB4011: There is a circular reference involving the import of file "c:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.CSharp.Targets". This file may have been imported more than once, or you may have attempted to import the main project file. All except the first instance of this file will be ignored.
Errors:
C:\Users\assrock\Documents\JavaBind\JavaBind\JavaBind.csproj (Build) ->
C:\Program Files (x86)\MSBuild\Novell\Xamarin.Android.Bindings.targets (ExportJarToXml target) ->
    C:\Program Files (x86)\MSBuild\Novell\Xamarin.Android.Bindings.targets(170,5): error MSB6006: "java.exe" exited with code 1.
     1 Warning(s)
     1 Error(s)
Time Elapsed 00:00:00.4730270
--------------------- Fertig ---------------------
Build: 1 Fehler, 0 Warnungen

Для android-support-v4.jar я нашел эти xml-файлы и поместил их в каталог Transforms:

EnumFields.xml

<enum-field-mappings>
  <mapping jni-class="android/support/v4/app/FragmentActivity$FragmentTag" clr-enum-type="Android.Support.V4.App.FragmentTagType">
    <field  jni-name="Fragment_id"    clr-name="Id"   value="1" />
    <field  jni-name="Fragment_name"  clr-name="Name" value="0" />
    <field  jni-name="Fragment_tag"   clr-name="Tag"  value="2" />
  </mapping>
</enum-field-mappings>

Энумметодс.xml

<enum-method-mappings>
  <mapping jni-class="android/support/v4/app/Fragment$SavedState">
        <method jni-name="writeToParcel"  parameter="p1"    clr-enum-type="Android.OS.ParcelableWriteFlags" />
    <method jni-name="writeToParcel"  parameter="flags" clr-enum-type="Android.OS.ParcelableWriteFlags" />
    </mapping>
</enum-method-mappings>

Метаданные.xml

<metadata>
  <remove-node path="/api/package[@name='android.support.v4.app']/class[@name='BackStackState']" />
  <remove-node path="/api/package[@name='android.support.v4.app']/class[@name='FragmentState']" />
  <remove-node path="/api/package[@name='android.support.v4.app']/class[@name='FragmentManagerState']" />
  <remove-node path="/api/package[@name='android.support.v4.widget']/class[@name='CursorAdapter']/implements[@name='android.support.v4.widget.CursorFilter.CursorFilterClient']" />
  <remove-node path="/api/package[@name='android.support.v4.widget']/class[@name='CursorAdapter']/field[@name='mCursorFilter']" />

  <remove-node path="/api/package[@name='android.support.v4.content']/class[@name='AsyncTaskLoader.LoadTask']" />
  <!-- FIXME:
        This method is an override of another method in the base types.
        The base method expects JLO, but this method returns Cursor.
        So we somehow have to fill the gap between them.
  -->
  <remove-node path="/api/package[@name='android.support.v4.content']/class[@name='CursorLoader']/method[@name='loadInBackground']" />

  <remove-node path="/api/package[@name='android.support.v4.view.accessibility']/class[@name='AccessibilityNodeInfoCompat.AccessibilityNodeInfoIcsImpl']" />
  <remove-node path="/api/package[@name='android.support.v4.widget']/class[@name='CursorAdapter.ChangeObserver']" />
  <remove-node path="/api/package[@name='android.support.v4.view.accessibility']/class[@name='AccessibilityNodeInfoCompat.AccessibilityNodeInfoIcsImpl']" />
  <remove-node path="/api/package[@name='android.support.v4.view.accessibility']/class[@name='AccessibilityNodeInfoCompat.AccessibilityNodeInfoStubImpl']" />
  <remove-node path="/api/package[@name='android.support.v4.view']/interface[@name='ViewPager.OnAdapterChangeListener']" />

  <attr path="/api/package[@name='android.support.v4.app']/class[@name='LoaderManager']/method[@name='initLoader']/parameter[@name='p2']" name="type">android.support.v4.app.LoaderManager.LoaderCallbacks</attr>
  <attr path="/api/package[@name='android.support.v4.app']/class[@name='LoaderManager']/method[@name='initLoader']/parameter[@name='callback']" name="type">android.support.v4.app.LoaderManager.LoaderCallbacks</attr>
  <attr path="/api/package[@name='android.support.v4.app']/class[@name='LoaderManager']/method[@name='initLoader']" name="return">android.support.v4.content.Loader</attr>
  <attr path="/api/package[@name='android.support.v4.app']/class[@name='LoaderManager']/method[@name='restartLoader']/parameter[@name='p2']" name="type">android.support.v4.app.LoaderManager.LoaderCallbacks</attr>
  <attr path="/api/package[@name='android.support.v4.app']/class[@name='LoaderManager']/method[@name='restartLoader']/parameter[@name='callback']" name="type">android.support.v4.app.LoaderManager.LoaderCallbacks</attr>
  <attr path="/api/package[@name='android.support.v4.app']/class[@name='LoaderManager']/method[@name='restartLoader']" name="return">android.support.v4.content.Loader</attr>
</metadata>

person Flo    schedule 03.05.2012    source источник
comment
Проголосовал из-за твоего потрясающего имени пользователя на компьютере assrock!   -  person Cheesebaron    schedule 25.05.2012
comment
Просто чтобы что-то исключить, я бы переместил ваш android-sdk из /program files/ в каталог без пробелов c:/android-sdk   -  person Blundell    schedule 05.06.2012
comment
Я считаю, что успешно связал ActionBarSherlock в Mono для Android. Дополнительную информацию и ссылку для скачивания с исходным кодом см. в моем блоге: craigsprogramming.com/2012/07/   -  person craigrs84    schedule 13.07.2012


Ответы (4)


ActionBarSherlock включает в себя элементы пользовательского интерфейса, стили и другие вещи, которые нельзя скомпилировать в файл JAR. Об этом есть примечание в часто задаваемых вопросах ActionBarSherlock.

Вопрос. Почему ActionBarSherlock является проектом библиотеки, тогда как исходная библиотека совместимости представляет собой только файл .jar?

A: Реализация настраиваемой панели действий в ActionBarSherlock зависит от стилей, тем, макетов и рисунков для правильного отображения. Из-за ограничений файлов Android и .jar в настоящее время это невозможно сделать каким-либо другим способом.

Изменить. Дополнительная информация о попытках совместного использования ресурсов между проектами библиотек в Mono для Android приведена по этой ссылке: http://mono-for-android.1047100.n5.nabble. Короткий ответ: на данный момент это не выглядит возможным.

person Christian    schedule 05.06.2012

Я считаю, что успешно связал ActionBarSherlock в Mono для Android.

Вам нужно упаковать java-файлы как JAR-файл, но без ресурсов и без файлов классов R java. Прежде чем упаковывать файлы, убедитесь, что в настройках Android установлен флажок «Является библиотекой», чтобы идентификаторы ресурсов не создавались как константы и не встраивались в ваши скомпилированные классы Java.

Сделав это, вы можете использовать последнюю версию Mono для Android для привязки файла JAR.

Ресурсы нужно копировать отдельно из JAR-файла и размещать прямо в основном проекте андроид-приложения. К сожалению, в настоящее время нет возможности изолировать ресурсы в отдельном проекте библиотеки при использовании Mono для Android, но я ожидаю, что это скоро изменится.

Наконец, вам нужно отредактировать файл проекта C-Sharp, чтобы он автоматически создавал новую версию файла класса Java com.actionbarsherlock.R при каждой перестройке. Это необходимо для синхронизации всех ваших идентификаторов ресурсов.

Я, возможно, пропустил шаг или два, но это самые важные.

Пожалуйста, смотрите мой пост в блоге для получения дополнительной информации и ссылки для скачивания с исходным кодом:

http://www.craigsprogramming.com/2012/07/actionbarsherlock-with-mono-for-android.html

person craigrs84    schedule 13.07.2012

Это может показаться подходом кувалды, но, скорее всего, решит вашу проблему...

Я бы предложил использовать Maven, который гораздо лучше справляется с этими зависимостями. Вы сможете ссылаться на проект ActionBarSherlock в своем POM, а MVN будет управлять зависимостями для вас.

Я также могу подтвердить, что исходный ответ правильный - существует ограничение на включение файлов JAR, содержащих ресурсы макета.

person Booger    schedule 07.06.2012

Похоже, Xamarin решил проблему с привязкой ActionBarSherlock

https://bugzilla.xamarin.com/show_bug.cgi?id=6186

Это исправление включено в версию 4.2.5, которая теперь доступна на альфа-канале.

person Timur Gilfanov    schedule 04.08.2012