xamarin.jar-Binding of ActionBarSherlock for Mono for Androi



我想在我的 Mono For Android 项目中绑定 ActionBarSherlock 的 jar 库。我崇敬这个文档:http://docs.xamarin.com/android/tutorials/Binding_a_Java_Library_(.jar(

我已经成功绑定了 android-support-v4.jar这是 ActionBarSherlock 需要的。但是当我尝试编译动作栏夏洛克.jar时,它给了我以下错误消息:

Target ResolveLibraryProjects:
    Skipping target "ResolveLibraryProjects" because it has no inputs.
    Target _ResolveMonoAndroidSdks:
        MonoAndroid Tools: C:Program Files (x86)MSBuildNovell
        MonoAndroid Framework: C:Program Files (x86)Reference AssembliesMicrosoftFrameworkMonoAndroidv2.2;C:Program Files (x86)Reference AssembliesMicrosoftFrameworkMonoAndroidv1.0
        Android SDK: C:Program Files (x86)Androidandroid-sdk
        Java SDK: C:Program Files (x86)Javajdk1.6.0_31
    Target ExportJarToXml:
          SourceJars:
            Jarsactionbarsherlock.jar
          ReferenceJars:
            Jarsandroid-support-v4.jar
        C:Program Files (x86)Javajdk1.6.0_31binjava.exe -jar "C:Program Files (x86)MSBuildNovelljar2xml.jar" --jar=C:UsersassrockDocumentsJavaBindJavaBindJarsactionbarsherlock.jar --ref="C:Program Files (x86)Androidandroid-sdkplatformsandroid-8android.jar" --out=C:UsersassrockDocumentsJavaBindJavaBindobjReleaseapi.xml --ref=C:UsersassrockDocumentsJavaBindJavaBindJarsandroid-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)MSBuildNovellXamarin.Android.Bindings.targets(170,5): error MSB6006: "java.exe" exited with code 1.
    Task "JarToXml" execution -- FAILED
    Done building target "ExportJarToXml" in project "C:UsersassrockDocumentsJavaBindJavaBindJavaBind.csproj".-- FAILED
Done building project "C:UsersassrockDocumentsJavaBindJavaBindJavaBind.csproj".-- FAILED
Build FAILED.
Warnings:
C:Program Files (x86)MSBuildNovellXamarin.Android.Bindings.targets(40,11): warning MSB4011: There is a circular reference involving the import of file "c:WindowsMicrosoft.NETFrameworkv4.0.30319Microsoft.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:UsersassrockDocumentsJavaBindJavaBindJavaBind.csproj (Build) ->
C:Program Files (x86)MSBuildNovellXamarin.Android.Bindings.targets (ExportJarToXml target) ->
    C:Program Files (x86)MSBuildNovellXamarin.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 目录中:

枚举字段.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>

ActionBarSherlock 包含 UI 元素、样式和其他无法编译为 JAR 文件的内容。在ActionBarSherlock FAQ上有一个关于此的说明。

问:为什么 ActionBarSherlock 是一个库项目,而原始兼容性库只是一个.jar?

答:ActionBarSherlock 中的自定义操作栏实现依赖于样式、主题、布局和可绘制对象才能正确显示。由于Android和.jar文件的限制,目前无法通过任何其他方式完成此操作。

编辑:在此链接中,有一些关于尝试在Mono for Android中的库项目之间共享资源的其他信息:http://mono-for-android.1047100.n5.nabble.com/Resources-from-a-Library-Project-td4657828.html。简短的回答是目前看起来是不可能的。

我相信

我已经成功地将ActionBarSherlock绑定到Android的Mono中。

您需要将 java 文件打包为 JAR 文件,但没有资源,也没有 R Java 类文件。在打包文件之前,请确保选中 Android 设置中显示"是库"的框,以便资源 ID 不会创建为常量并内联到已编译的 Java 类中。

完成此操作后,您可以使用最新版本的Mono for Android来绑定JAR文件。

资源需要与JAR文件分开复制,并直接放置在主Android应用程序项目中。不幸的是,目前在使用 Android 版 Mono 时,无法将资源隔离在单独的库项目中,但我希望这种情况很快就会改变。

最后,您需要编辑 C-Sharp 项目文件,以便每次重建时它都会自动创建新版本的 com.actionbarsherlock.R java 类文件。这是保持所有资源 ID 同步所必需的。

我可能错过了一两步,但这些是最重要的一步。

请参阅我的博客文章以获取更多信息和源代码下载链接:

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

这似乎是一种大锤方法,但可能会解决您的问题......

我建议使用 Maven 进行构建,它可以更好地处理这些依赖项。 您将能够在POM中引用ActionBarSherlock项目,MVN将为您管理依赖项。

我也可以确认原始答案是正确的 - 包含包含布局资源的 JAR 文件存在限制。

看起来 Xamarin 解决了 ActionBarSherlock 绑定问题

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

此修复程序已包含在 4.2.5 中,该版本现已在 alpha 频道上可用。

最新更新