Android API Guides---Verifying App Behavior on the Android Runtime (ART)

在Android 4.4系统,大家都开始推出新的Andr​​oid运行时,ART。这种运行提供了许多可提高性能和Android平台和应用的平滑新功能。 (您可以找到有关介绍造型艺术的新功能的更多信息。)


目前,ART可在许多Android 4.4系统的设备,如Nexus的4,5的Nexus,Nexus 7和谷歌Play版设备。这时,所有的设备仍然使用的Dalvik作为默认运行。我们鼓励您测试您的应用程序的兼容性ART并利用艺术的新功能。然而,就目前而言,你也应该小心保持与Dalvik的兼容性。


本文档可以让你知道的事情看迁移现有的应用程序时要与ART兼容的。艺术运行时,大多数应用程序应该只是工作。然而,一些技术,对Dalvik的工作,不要艺术作品。本文讨论的一些问题。


解决垃圾回收(GC)问题


在Dalvik的,经常应用发现它很有用显式调用System.gc()的提示垃圾回收(GC)。这应该是远远艺术没有那么必要,特别是如果你调用垃圾收集,以防止GC_FOR_ALLOC型发生或减少碎片。可以验证其运行正由调用System.getProperty(“java.vm.version”)。如果艺术是在使用中,该属性的值为“2.0.0”或更高。


此外,压缩垃圾收集器是根据在Android开源项目(AOSP)的开发,以提高内存管理。正因为如此,你应该避免使用与压实GC(如保存指向对象实例的数据)不兼容的技术。这是一个应用程序,使用Java本地接口(JNI)显得尤为重要。有关详细信息,请参阅防止JNI问题。


防止JNI问题


ART的JNI比的Dalvik的有点严格。它是用CheckJNI模式捕捉常见的问题一个特别好的主意。如果您的应用程序利用了C / C ++代码,你应该阅读以下文章:


Android的调试用JNI CheckJNI


垃圾收集问题检查JNI代码


艺术有一个正在开发的压缩垃圾收集器在Android开源项目(AOSP)。一旦压缩垃圾收集器在使用时,对象可能在存储器移动。如果使用C / C ++代码,不执行与压实GC不兼容的操作。我们加强CheckJNI确定一些潜在的问题(如在ICS JNI本地参考更改说明)。


特别是观看一个领域是使用get ... ArrayElements()和Release ... ArrayElements()函数。在与非压缩GC运行时间,获取... ArrayElements()函数通常返回实际内存支持数组对象的引用。如果你更改了返回数组的元素之一,数组对象本身改变(与参数释放... ArrayElements()通常忽略)。然而,如果压缩的GC是在使用中,获取... ArrayElements()函数可能返回存储器的副本。如果你滥用的参考,当压缩GC在使用中,这可能会导致内存损坏或其他问题。例如:


如果您对返回数组的元素进行任何更改,必须调用相应的释放... ArrayElements()函数,当你完成,以确保您所做的更改正确复制到底层数组对象。
当你释放内存数组元素,必须使用相应的模式,这取决于你所做的修改:
如果你没有做数组元素的任何变化,使用JNI_ABORT模式,它释放内存,而不复制变回为基础数组对象。
如果你修改了阵列,并且不需要参考任何更多,使用代码0(更新数组对象并释放内存的复印件)。
如果更改到您要提交阵列,并且要保留数组的副本,请使用JNI_COMMIT(其中更新底层数组对象并保留复印件)。
当你调用Release ... ArrayElements(),返回最初是由Get ... ArrayElements返回相同的指针()。例如,它不是安全递增原来的指针(通过返回数组的元素扫描),然后传递递增的指针,以释放... ArrayElements()。通过这项修改指针可能会导致被释放错误的内存,导致内存损坏。
错误处理


ART的JNI抛出的数,其中的Dalvik没有的情况下错误。 (再次,你可以通过CheckJNI测试赶上很多这样的情况。)


例如,如果RegisterNatives被调用的方法,其不存在(也许是因为通过一工具如ProGuard的除去方法),ART现在正确抛出的NoSuchMethodError:

08-12 17:09:41.082 13823 13823 E AndroidRuntime: FATAL EXCEPTION: main
08-12 17:09:41.082 13823 13823 E AndroidRuntime: java.lang.NoSuchMethodError:
    no static or non-static method
    "Lcom/foo/Bar;.native_frob(Ljava/lang/String;)I"
08-12 17:09:41.082 13823 13823 E AndroidRuntime:
    at java.lang.Runtime.nativeLoad(Native Method)
08-12 17:09:41.082 13823 13823 E AndroidRuntime:
    at java.lang.Runtime.doLoad(Runtime.java:421)
08-12 17:09:41.082 13823 13823 E AndroidRuntime:
    at java.lang.Runtime.loadLibrary(Runtime.java:362)
08-12 17:09:41.082 13823 13823 E AndroidRuntime:
    at java.lang.System.loadLibrary(System.java:526)
ART还记录如果RegisterNatives被称为没有方法的错误(logcat中可见):

W/art     ( 1234): JNI RegisterNativeMethods: attempt to register 0 native
methods for <classname>
此外,JNI函数GetFieldID()和GetStaticFieldID()现在可以正确地抛出简单地返回null NoSuchFieldError代替。同样,的GetMethodID()和GetStaticMethodID()现在可以正确地抛出的NoSuchMethodError。这可能会导致被抛出来的原生代码的Java调用方,因为未处理的异常或异常CheckJNI故障。这使得它特别重要的与CheckJNI模式下测试技术兼容的应用程序。


技术预计JNI CallNonvirtual用户...方法()方法(如CallNonvirtualVoidMethod())中使用的方法的声明类,而不是一个子类,因为需要通过JNI规范。


防止堆栈大小问题


Dalvik的有原生和Java代码分离栈,具有32KB的默认的Java堆栈大小和1MB的默认本机堆栈大小。艺术有更好的地方了统一的堆栈。通常,对ART线程堆栈大小应大致相同的Dalvik。但是,如果您明确设置堆栈大小,您可能需要重新审视这些值在ART正在运行的应用。


在Java中,审核要求到指定一个明确的堆栈大小Thread的构造函数。例如,您将需要的,如果发生的StackOverflowError增加大小。
在C / C ++,对于还通过JNI运行Java代码的线程在评论中使用pthread_attr_setstack()和pthread_attr_setstacksize()的。下面是记录错误的一个例子,当一个应用程序试图调用JNI AttachCurrentThread()的时候pthread的尺寸太小:

F/art: art/runtime/thread.cc:435]
    Attempt to attach a thread with a too-small stack (16384 bytes)
对象模型更改
Dalvik的错误让子类覆盖包私有方法。 ART问题在这种情况下的警告:

Before Android 4.1, method void com.foo.Bar.quux()
would have incorrectly overridden the package-private method in
com.quux.Quux
如果您打算在不同的包来覆盖类的方法,申报方法公开或保护。


对象现在拥有私有字段。这在他们的类层次结构领域反映应用程序应注意不要试图看对象的字段。例如,如果你迭代一个类层次结构作为一个序列化框架的一部分,当停止

Class.getSuperclass() == java.lang.Object.class
而不是继续,直到该方法返回null。
如果没有参数,而不是一个空数组代理InvocationHandler.invoke()现在收到空。此行为以前记录,但Dalvik的不是正确的处理。中的Mockito以前的版本有这个困难,所以用先进的测试时使用的一个更新版本的Mockito。


修复AOT编译问题


ART的名列前茅的时间(AOT)Java编译应适用于所有标准的Java代码。编译是由ART的dex2oat工具执行;如果遇到要dex2oat在安装时相关的任何问题,请告诉我们(见报告问题),这样我们就可以尽快解决这些问题。几个问题要注意:


有技术并在安装时比不Dalvik的字节码更严格的验证。通过Android编译工具生成的代码应该罚款。然而,一些后处理工具(尤其是执行模糊处理工具),可能会产生由Dalvik的耐受性,但由ART拒绝的无效文件。我们一直与工具厂商合作,以查找和解决这些问题。在许多情况下,让你的工具的最新版本,并重新生成DEX文件可以解决这些问题。
由该技术验证标记的一些典型的问题包括:
无效的控制流
不平衡moniterenter / moniterexit
长度为0的参数类型列表的大小
有些应用程序有,/数据/达尔维克缓存,在/系统/框架安装.odex文件格式的依赖或DexClassLoader优化的输出目录。这些文件现在ELF文件而不是DEX文件的扩展形式。虽然ART试图遵循相同的命名和锁定规则的Dalvik,应用程序不应该依赖于文件格式;格式如有更改,恕不另行通知。
报告问题


如果碰上未到期到App JNI的问题,通过在https://code.google.com/p/android/issues/list Android开源项目事件跟踪报道他们的任何问题。包括“亚行错误报告”,并在谷歌Play商店,如果提供给应用程序的链接。否则,如果可能的话,附加的APK再现问题。注意事项(包括附件)为公开可见。

你可能感兴趣的:(java,android,api,sdk,AppBehavior)