2011-09-01 30 views
1

我最近一直在寻找处理API级别碎片和在你的源代码,以支持不同的API级别发现了一个伟大tutorial的Android的Dalvik核查Eclair的

正如教程说明,以避免运行时使用比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开始时CameraActivity我将收到的VerifyError异常运行APK疑似编译。

但令我感到惊讶的是,当我在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:我已经检查了setDisplayOrientation确实不存在于Eclair 2.1中。我在调用方法之前尝试删除Build Version SDK检查。如果我只是调用方法,我会收到NoSuchMethod异常。但如果IF在那里,我不会得到VerifyError!

回答

3

从Android 2.0开始,Dalvik验证器更聪明,只需检查运行时实际使用的类。

也就是说,您在此处显示的代码仅适用于在旧版本平台上运行时从未触摸CameraActivity类的情况。鉴于这不是你正在展示的内容,可能有一个解释是,在API的一些较旧版本的平台上,SDK尚未提供。

+0

感谢您的快速响应。我在这里担心的是CameraActivity实际上可以在Eclair 2.1上启动并运行良好。在甜甜圈(1.6)或Cupcake(1.5)上,CameraActivity在VerifyError问题开始时会崩溃。 – hnviet

+0

正如我所说,在一些较旧的设备上可能会有此方法的早期版本。一般来说,如果你有一个使用更新版本平台的API的类,你需要确保你永远不会让这个类的任何代码在旧版本的平台上执行(这会导致类成为初始化并在那一点上导致例外)。 – hackbod

+0

是的,我确实理解在旧平台上处理库/ API不可用的问题。我关心的不是为什么它不适用于2.0之前的版本,因为它确切地说应该是这样。我的问题是为什么它在2上运行。1,当它不应该。我一直在研究这个问题,但找不到答案。 – hnviet