简体   繁体   English

Eclair中的Android Dalvik验证

[英]Android Dalvik Verification in Eclair

I have recently been looking at handling API levels fragmentation and found a great tutorial on supporting different API Levels in your source code: 我最近一直在研究处理API级别碎片,并在源代码中找到了一个很好的教程来支持不同的API级别:

As stated in the tutorial, in order to avoid run-time error of using newer classes/methods than the API Level ones should check the API level and use lazy loading. 如本教程中所述,为了避免使用比API级别新的类/方法,在运行时出现错误,应检查API级别并使用延迟加载。

I have checked the code and can confirm that on Android <2.0 you must use lazy loading to avoid VerifyError. 我已经检查了代码,可以确认在Android <2.0上,您必须使用延迟加载来避免VerifyError。 What was a huge surprise for me was that in 2.1 the lazy loading is not necessary anymore. 让我感到惊讶的是,在2.1中不再需要延迟加载。

I will use the Camera.setDisplayOrientation method to demonstrate the issue. 我将使用Camera.setDisplayOrientation方法来演示该问题。 The method was introduced in Froyo 2.2. 该方法在Froyo 2.2中引入。

import android.hardware.Camera;
...
public class CameraActivity extends Activity implements SurfaceHolder.Callback{
   Camera mCamera;

   ...

   public void surfaceChanged(SurfaceHolder holder, int format, int w, int h){
      final int APIversion = Integer.parseInt(Build.VERSION.SDK);
      if (APIversion >= Build.VERSION_CODES.FROYO){
         camera.setDisplayOrientation(90);
      }
      ...
   }
}

The code is compiled using the Froyo Compiler (API 8) 使用Froyo编译器(API 8)编译代码

As suspected if I run the APK on a Android version <2.0 I will receive an VerifyError exception when starting the CameraActivity. 怀疑如果我在Android版本<2.0上运行APK,则启动CameraActivity时会收到VerifyError异常。

But what amazes me is that when I run the same APK on Eclair 2.1 the application is loaded without any problem. 但是令我惊讶的是,当我在Eclair 2.1上运行相同的APK时,应用程序加载没有任何问题。 And I have double checked the Camera interface, and found that the setDisplayOrientation method was only introduced in Froyo 2.2. 而且我仔细检查了Camera界面,发现setDisplayOrientation方法仅在Froyo 2.2中引入。

On the contrary if I try to call the method I will get an exception, ie 相反,如果我尝试调用该方法,则会得到一个异常,即

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h){    
    final int APIversion = Integer.parseInt(Build.VERSION.SDK);
    camera.setDisplayOrientation(90);
}

On Eclair this will throw NoSuchMethodError . Eclair上,这将引发NoSuchMethodError

Why does it work? 它为什么有效? Does it have anything to do with class verification being turned off? 它与关闭类验证有关吗?

PS : I have checked that the setDisplayOrientation indeed doesn't exist in Eclair 2.1. PS :我检查了setDisplayOrientation在Eclair 2.1中确实不存在。 I did it by trying to remove the Build Version SDK check before calling the method. 我通过在调用方法之前尝试删除Build Version SDK检查来做到这一点。 If I just call the method I will receive NoSuchMethod exception. 如果我只是调用该方法,我将收到NoSuchMethod异常。 But if the IF is there I don't get the VerifyError! 但是,如果IF存在,我就不会收到VerifyError!

Starting with Android 2.0 the Dalvik verifier is smarter about only checking classes that are actually used while running. 从Android 2.0开始,Dalvik验证程序更聪明,仅检查运行时实际使用的类。

That said, the code you show here would only work if you never touch the CameraActivity class when running on older versions of the platform. 也就是说,您在此处显示的代码仅在在较旧版本的平台上运行时从未触摸CameraActivity类时才起作用。 Given that isn't what you are showing, an explanation may be that on some older builds of the platform that API was there but not yet available in the SDK. 鉴于您所显示的不是您所显示的,可能是在一些较早版本的平台上有API可用,但SDK中尚不可用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM