2011-09-01 31 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