我最近一直在考虑处理API级别碎片,并且在源代码中支持不同的API级别时发现了一个很棒的tutorial:
如本教程所述,为了避免使用比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)编译代码
如果我在Android版本< 2.0上运行APK,我会在启动CameraActivity时收到VerifyError异常。
但令我惊讶的是,当我在 Eclair 2.1 上运行相同的APK时,应用程序加载没有任何问题。我已经仔细检查了Camera接口,发现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 :我已经检查过Eclair 2.1中确实不存在setDisplayOrientation。我是通过在调用方法之前尝试删除Build Version SDK检查来完成的。如果我只是调用方法,我将收到NoSuchMethod异常。但如果IF在那里我没有得到VerifyError!
答案 0 :(得分:3)
从Android 2.0开始,Dalvik验证程序更智能,只检查运行时实际使用的类。
也就是说,您在此处显示的代码只有在平台的旧版本上运行时从未触及CameraActivity类才有效。鉴于这不是您所展示的内容,解释可能是在该平台的某些旧版本上,API存在但尚未在SDK中提供。