简体   繁体   中英

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:

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.

I have checked the code and can confirm that on Android <2.0 you must use lazy loading to avoid VerifyError. What was a huge surprise for me was that in 2.1 the lazy loading is not necessary anymore.

I will use the Camera.setDisplayOrientation method to demonstrate the issue. The method was introduced in 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)

As suspected if I run the APK on a Android version <2.0 I will receive an VerifyError exception when starting the CameraActivity.

But what amazes me is that when I run the same APK on Eclair 2.1 the application is loaded without any problem. And I have double checked the Camera interface, and found that the setDisplayOrientation method was only introduced in 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 .

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. I did it by trying to remove the Build Version SDK check before calling the method. If I just call the method I will receive NoSuchMethod exception. But if the IF is there I don't get the VerifyError!

Starting with Android 2.0 the Dalvik verifier is smarter about only checking classes that are actually used while running.

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. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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