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, i.e.
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!