在armeabi-v7a设备上运行仅使用armeabi构建的应用程序?

时间:2013-07-02 15:06:36

标签: android build xamarin.android xamarin cpu-architecture

Xamarin documentation对此有点不清楚。如果我构建我的应用程序时只在构建首选项中勾选了armeabi,那么我的应用程序是否会

  1. 适用于Play商店中的v7a设备吗?
  2. 在v7a设备上运行?
  3. 如果它确实运行,是否有任何功能,如使用会导致意外行为或崩溃的线程?

    我有一个简单的应用程序,并试图保持它的小。另外,我没有v7a设备来进行快速实验。

    澄清:

    虽然似乎已经明确接受了仅使用amreabi库编译Android应用程序是“安全但不太高效”(请参阅​​此优秀帖子:Why use armeabi-v7a code over armeabi code?),Xamarin docs on CPU architecture ,我认为适用于他们编译的.so库,说:

      

    重要的是要记住使用的armeabi运行时   Xamarin.Android是线程安全的。如果一个应用程序有armeabi   支持部署到armeabi-v7a设备,很多很奇怪   无法解释的例外情况将会发生。

    此后,我已经能够测试我的应用程序,该应用程序是在v7a设备上使用armeabi编译的,并且没有遇到任何“奇怪且无法解释的异常”YET。

    更新

    看起来Xamarin文档已经更新,现在(2014-07-14)读取:

      

    重要的是要记住使用的armeabi运行时   Xamarin.Android 不是线程安全的。如果有应用程序   armeabi支持被部署到armeabi-v7a设备上,很奇怪   将发生无法解释的例外情况。

4 个答案:

答案 0 :(得分:8)

根据Xamarin Android文档,armeabi代码将在多核armeavi-v7设备上以意外方式崩溃。

http://docs.xamarin.com/guides/android/advanced_topics/cpu_architecture

  

第1.1节

     

注意:Xamarin.Android的armeabi代码不是线程安全的,不应该   用于多CPU armeabi-v7a设备(如下所述)。运用   单核armeabi-v7a设备上的aremabi代码是安全的。

Xamarin Android要求包含armeabi-v7a的原因与线程安全内存访问有关。简单地说,armeabi指令集缺少安全锁定SMP设备上的内存所需的指令。

可以在此错误报告中找到有关该问题的最全面的讨论:https://bugzilla.xamarin.com/show_bug.cgi?id=7013

  

Jonathan Pryor 2012-09-20 11:41:45 EDT

     

据我所知,安全使用armeabi(几乎)是不可能的   SMP armeabi-v7a设备上的库。这是因为armeabi缺乏CPU   安全锁定SMP设备上的数据所必需的说明,所以如果armeabi   library包含必须保护以防止来自多个访问的数据   线程,它被破坏了,libmonodroid.so就是这样一个库。这可能是   通过创建一个动态确定运行时的libmonodroid.so来修复   CPU,允许它使用armeabi或armeabi-v7a锁定指令   相应地,但尚未完成,以及实施时间表   不明。

     

因此,如果您的应用程序将在SMP硬件上运行,则应包括   使用您的应用程序的armeabi-v7a运行时。这可以在项目选项中完成    对话框。

这些崩溃很罕见,但是由于遇到随机内存损坏和分段错误而很难进行调试。

我能够在Galaxy S3上可靠地重现这个问题。演示崩溃的一些示例代码在此错误报告中:https://bugzilla.xamarin.com/show_bug.cgi?id=7167


此错误是否会影响Android上的其他NDK应用程序。但它肯定会影响Xamarin Android。

答案 1 :(得分:7)

我点击并阅读了Xamarin的评论。在阅读它们的基础上,我认为你提出了错误的问题。你问的问题的答案是(正如CommonsWare在他的评论中所述),“是的,除非Xamarin搞砸了什么”。不幸的是,他们的文档表明他们认为他们确实搞砸了。在他们的文档中有一些拼写错误,特别是在一个地方(第1.1节)他们说“线程安全”,当他们明确表示“不是线程安全”时。他们在第1.2节中正确地重申了这一点:

  

注意:Xamarin.Android的armeabi代码不是线程安全的,不应该   用于多CPU armeabi-v7a设备(如下所述)。运用   单核armeabi-v7a设备上的aremabi代码是安全的。

我认为如果你结合第1.2和1.1节中的信息,很明显Xamarin告诉你的是什么。要清楚,我只是重述他们的文档所说的内容,而不是对其文档的真实性做出任何断言。也就是说,在armeabi libs(非线程安全)被加载到多核或多处理器设备上的情况下,可能发生不好的事情。这种情况可能是由于ICS(4.0.0-4.0.3)中的错误引起的。因此:

  

使用Xamarin.Android 4.2或更低版本构建的应用程序应明确指定armeabi-v7a作为唯一基于ARM的ABI

以下是他们的文档(已添加格式)的实际信息重新排列为可能有助于使其更清晰的订单:

  

来自第1.2.1节

     

注意:Xamarin.Android的armeabi代码非线程安全,不应在多CPU armeabi-v7a设备上使用(如下所述)。在单核armeabi-v7a设备上使用aremabi代码是安全的。

     

来自第1.1节

     

由于Android 4.0.0,4.0.1,4.0.2和4.0.3中存在错误,即使存在armeabi-v7a目录且该设备存在,也会从armeabi目录中获取本机库是一种armeabi-v7a设备。

     

注意:由于这些原因,强烈建议使用Xamarin.Android 4.2或更低版本构建的应用程序应明确指定armeabi-v7a作为唯一基于ARM的ABI。

我认为基于文档的其余部分,这是第1.1节中的第一段应该说的(粗体编辑是我的):

  

应用程序二进制接口将在下面详细讨论,   但重要的是要记住使用的armeabi运行时   Xamarin.Android 线程安全。如果一个应用程序有armeabi   支持部署到多CPU armeabi-v7a设备,很多很奇怪   无法解释的例外情况将会发生。

答案 2 :(得分:3)

http://www.arm.com/products/processors/instruction-set-architectures/index.php

如果你看一下这个图表,它解释了ARM处理器设计的精神。 ARM Design

新迭代扩展了基本功能集,但不进行更改。 NEON和SIMD需要直接引用才能使用,因此不能从ARMv5二进制文件中引用。除非你的二进制文件是巨大的(这是实际的可执行文件,而不是整个APK),否则我会编译两者并获得两全其美。有关详细信息,请参阅this question

无论如何,我会联系Xamarin来澄清那些略微加载的'无法解释的例外'声明。如果他们发现代码在多个处理器上运行时会出现问题,那么无论内核数量多少,他们的代码本质上都不是线程安全的。

答案 3 :(得分:0)

armeabi是一般基础,armeabi-v7a包含一些在armeabi指令集中找不到的附加指令。 v7a支持硬件浮点运算,如果它执行任何浮点运算,可以使代码更快。如果硬件支持,Android将首先尝试加载armeabi-v7a库,但如果没有,它将回退到armeabi版本。