Недавно я изучал фрагментацию уровней API и нашел отличный учебник по поддержке различных уровней API в ваш исходный код:
Как указано в учебнике, во избежание ошибки во время использования новых классов/методов, чем уровень API, необходимо проверить уровень API и использовать ленивую загрузку.
Я проверил код и могу подтвердить, что на Android < 2.0 вы должны использовать ленивую загрузку, чтобы избежать VerifyError. Для меня было большим сюрпризом, так как в 2.1 ленивая загрузка больше не нужна.
Я использую метод Camera.setDisplayOrientation
, чтобы продемонстрировать проблему. Метод был введен в 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);
}
...
}
}
Код компилируется с использованием компилятора Froyo (API 8)
Как и предполагалось, если я запустил APK в версии для Android версии 2.0, я получаю исключение VerifyError при запуске CameraActivity.
Но меня удивляет то, что когда я запускаю тот же APK на Eclair 2.1, приложение загружается без каких-либо проблем. И я дважды проверил интерфейс камеры и обнаружил, что метод setDisplayOrientation был введен только в Froyo 2.2.
Напротив, если я попытаюсь вызвать метод, я получу исключение, т.е.
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h){
final int APIversion = Integer.parseInt(Build.VERSION.SDK);
camera.setDisplayOrientation(90);
}
В Eclair это вызовет NoSuchMethodError
.
Почему это работает? Имеет ли это какое-либо отношение к отключению проверки класса?
PS: я проверил, что setDisplayOrientation действительно не существует в Eclair 2.1. Я сделал это, пытаясь удалить проверку версии SDK версии до вызова метода. Если я просто вызову метод, я получу исключение NoSuchMethod. Но если IF есть, я не получаю VerifyError!