validation错误部署在API 1.6上

在Android 1.6上部署我的应用程序时遇到向后兼容性问题。 我在这段代码上得到一个VerifyError:

if(android.os.Build.VERSION.SDK_INT >= 11) { getActionBar().setBackgroundDrawable(getResources().getDrawable(R.drawable.actionbar_bg)); } 

这并不出乎意料,因为getActionBar()在API 11之前不存在,但是1.6之后(API 5和更高版本?)根据logcat消息来构build所有的半优雅的环境,比如在API级别上部署8器件;

 06-27 16:47:04.333: INFO/dalvikvm(11529): Could not find method com.me.app.MyActivity.getActionBar, referenced from method com.me.app.MyActivity.init 06-27 16:47:04.333: WARN/dalvikvm(11529): VFY: unable to resolve virtual method 1090: Lcom.me.app.MyActivity;.getActionBar ()Landroid/app/ActionBar; 06-27 16:47:04.333: DEBUG/dalvikvm(11529): VFY: replacing opcode 0x6e at 0x004f 06-27 16:47:04.333: DEBUG/dalvikvm(11529): VFY: dead code 0x0052-005f in Lcom.me.app.MyActivity;.init (Z)V 

1.6和更早版本不会这样做,而是抛出一个VerifyError:

 06-27 16:23:45.561: ERROR/dalvikvm(427): Could not find method com.me.app.MyActivity.getActionBar, referenced from method com.me.app.MyActivity.init 06-27 16:23:45.561: WARN/dalvikvm(427): VFY: unable to resolve virtual method 1090: Lcom/me/app/MyActivity;.getActionBar ()Landroid/app/ActionBar; 06-27 16:23:45.561: WARN/dalvikvm(427): VFY: rejecting opcode 0x6e at 0x004f 06-27 16:23:45.561: WARN/dalvikvm(427): VFY: rejected Lcom/me/app/MyActivity;.init (Z)V 06-27 16:23:45.561: WARN/dalvikvm(427): Verifier rejected class Lcom/me/app/MyActivity; 06-27 16:23:45.561: WARN/dalvikvm(427): Class init failed in newInstance call (Lcom/me/app/MyActivity;) 06-27 16:26:44.841: ERROR/AndroidRuntime(427): Uncaught handler: thread main exiting due to uncaught exception 06-27 16:26:44.941: ERROR/AndroidRuntime(427): java.lang.VerifyError: com.me.app.MyActivity 06-27 16:26:44.941: ERROR/AndroidRuntime(427): at java.lang.Class.newInstanceImpl(Native Method) 06-27 16:26:44.941: ERROR/AndroidRuntime(427): at java.lang.Class.newInstance(Class.java:1472) 06-27 16:26:44.941: ERROR/AndroidRuntime(427): at android.app.Instrumentation.newActivity(Instrumentation.java:1097) 06-27 16:26:44.941: ERROR/AndroidRuntime(427): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2316) 06-27 16:26:44.941: ERROR/AndroidRuntime(427): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2417) 06-27 16:26:44.941: ERROR/AndroidRuntime(427): at android.app.ActivityThread.access$2100(ActivityThread.java:116) 06-27 16:26:44.941: ERROR/AndroidRuntime(427): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1794) 06-27 16:26:44.941: ERROR/AndroidRuntime(427): at android.os.Handler.dispatchMessage(Handler.java:99) 06-27 16:26:44.941: ERROR/AndroidRuntime(427): at android.os.Looper.loop(Looper.java:123) 06-27 16:26:44.941: ERROR/AndroidRuntime(427): at android.app.ActivityThread.main(ActivityThread.java:4203) 06-27 16:26:44.941: ERROR/AndroidRuntime(427): at java.lang.reflect.Method.invokeNative(Native Method) 06-27 16:26:44.941: ERROR/AndroidRuntime(427): at java.lang.reflect.Method.invoke(Method.java:521) 06-27 16:26:44.941: ERROR/AndroidRuntime(427): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791) 06-27 16:26:44.941: ERROR/AndroidRuntime(427): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549) 06-27 16:26:44.941: ERROR/AndroidRuntime(427): at dalvik.system.NativeStart.main(Native Method) 

有没有办法解决这个优雅,并向后兼容1.6?

编辑:所以我最终创build了一个具有静态方法的HoneycombHelper类:

 public class HoneycombHelper { public static void setActionBarBackgroundDrawable(Activity a, Drawable d) { a.getActionBar().setBackgroundDrawable(d); } ... } 

不知道这是不是最优雅的方式,但它似乎工作。

Solutions Collecting From Web of "validation错误部署在API 1.6上"

当Dalvik将您的类/函数从字节码编译为本地机器码时,它会编译所有语句,即使是条件语句也是如此。 在Android 1.6虚拟机上尝试parsing(validation) getActionBar函数,并且由于没有这样的函数,Dalvik会抛出VerifyError

你可以做下一个诀窍:

 class ActionBarHelper{ void setBackground(){ getActionBar().setBackgroundDrawable(...); } } ... if(android.os.Build.VERSION.SDK_INT >= 11) { new ActionBarHelper().setBackground(); } 

这样ActioBarHelper类才会在SDK 11+上运行时被编译/validation。 这将反过来允许调用getActionBar函数而不使用reflection(reflection是另一个可能的解决scheme来解决这个问题)。