适用于 Android 的 Mono 的 ActionBarSherlock 的 jar-Binding
Posted
技术标签:
【中文标题】适用于 Android 的 Mono 的 ActionBarSherlock 的 jar-Binding【英文标题】:jar-Binding of ActionBarSherlock for Mono for Android 【发布时间】:2012-05-13 08:32:28 【问题描述】:我想在我的 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\as-s-rock\Documents\JavaBind\JavaBind\Jars\actionbarsherlock.jar --ref="C:\Program Files (x86)\Android\android-sdk\platforms\android-8\android.jar" --out=C:\Users\as-s-rock\Documents\JavaBind\JavaBind\obj\Release\api.xml --ref=C:\Users\as-s-rock\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\as-s-rock\Documents\JavaBind\JavaBind\JavaBind.csproj".-- FAILED
Done building project "C:\Users\as-s-rock\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\as-s-rock\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>
EnumMethods.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>
【问题讨论】:
因为您在计算机“as-s-rock”上的出色用户名而投票! 只是为了排除一些问题,我会将您的 android-sdk 移出/program files/
并移至没有空格的目录 c:/android-sdk
我相信我已经成功地将ActionBarSherlock绑定到Mono for Android。更多信息请查看我的博文和源代码下载链接:craigsprogramming.com/2012/07/…
【参考方案1】:
ActionBarSherlock 包括 UI 元素、样式和其他无法编译到 JAR 文件中的内容。 ActionBarSherlock FAQ 上有关于此的说明。
问:为什么 ActionBarSherlock 是一个库项目,而原来的兼容性库只是一个 .jar?
A:ActionBarSherlock 中的自定义操作栏实现依赖于样式、主题、布局和可绘制对象才能正确显示。由于 Android 和 .jar 文件的限制,目前无法通过其他方式完成。
编辑:在此链接中有一些关于尝试在 Mono for Android 中跨库项目共享资源的其他信息:http://mono-for-android.1047100.n5.nabble.com/Resources-from-a-Library-Project-td4657828.html。简短的回答是目前看来不可能。
【讨论】:
【参考方案2】:我相信我已经在 Mono for Android 中成功绑定了 ActionBarSherlock。
您需要将 java 文件打包为 JAR 文件,但没有资源和 R java 类文件。在打包文件之前,请确保选中 Android 设置中的“Is Library”复选框,这样资源 ID 就不会被创建为常量并内联到已编译的 Java 类中。
完成此操作后,您可以使用 Android 版 Mono 的最新版本来绑定 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
【讨论】:
【参考方案3】:这似乎是一种大锤的方法,但很可能会解决您的问题...
我建议使用 Maven 构建,它可以更好地处理这些依赖关系。您将能够在您的 POM 中引用 ActionBarSherlock 项目,MVN 将为您管理依赖项。
我也可以确认原始答案是正确的 - 包含包含布局资源的 JAR 文件是有限制的。
【讨论】:
【参考方案4】:看起来 Xamarin 解决了 ActionBarSherlock 绑定问题
https://bugzilla.xamarin.com/show_bug.cgi?id=6186
此修复已包含在 4.2.5 中,现在可用于 Alpha 通道。
【讨论】:
以上是关于适用于 Android 的 Mono 的 ActionBarSherlock 的 jar-Binding的主要内容,如果未能解决你的问题,请参考以下文章
适用于 Android 的 Mono - 支持的架构 - 放弃 x86?
适用于 Android/iOS/WinPhone 的 Xamarin 通用层
gles2 动态壁纸转换为 c# (xamarin) 符合错误“...mono.android.TypeManager 无法应用于