32

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

我已经成功绑定了 ActionBarSherlock 需要的 android-support-v4.jar。但是当我尝试编译 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 目录中:

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

4 回答 4

5

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。简短的回答是目前看起来不可能。

于 2012-06-05T18:53:18.533 回答
3

我相信我已经成功地在 Mono for Android 中绑定了 ActionBarSherlock。

您需要将 java 文件打包为 JAR 文件,但没有资源和 R java 类文件。在打包文件之前,请确保选中 Android 设置中的“是库”框,这样资源 ID 就不会被创建为常量并内联到已编译的 Java 类中。

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

资源需要从 JAR 文件中单独复制,并直接放在主 android 应用程序项目中。不幸的是,目前在使用 Mono for Android 时,没有办法将资源隔离在单独的库项目中,但我预计这将很快改变。

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

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

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

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

于 2012-07-13T15:40:00.277 回答
1

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

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

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

于 2012-06-07T20:23:13.793 回答
0

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

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

此修复已包含在 4.2.5 中,现在可在 alpha 通道上使用。

于 2012-08-04T13:33:13.037 回答