的VerifyError部署在API 1.6 [英] VerifyError deploying on API 1.6

查看:183
本文介绍了的VerifyError部署在API 1.6的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Android 1.6部署我的应用程序,当我遇到一个向后兼容性问题。即时得到一个的VerifyError在这片code:

I've come across a backwards compatibility issue when deploying my application on android 1.6. Im getting a VerifyError on this piece of code:

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

这并不出人意料,因为getActionBar()不存在pre API 11,但后1.6(API 5及更高?)生成所有部署时半正常去解决这个根据logcat的消息即时得到例如API级别8设备上;

This is not unexpected since getActionBar() doesn't exist pre API 11, however post-1.6 (API 5 and higher?) builds all semi-gracefully go around this according to the logcat message im getting when deploying for example on a API level 8 device;

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:

1.6 and earlier wont do this but instead throw a 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?

Is there a way to fix this elegantly and have backwards compatibility to 1.6?

编辑: 所以,我结束了创建静态方法HoneycombHelper类:

So I ended up creating a HoneycombHelper class with static methods:

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

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

Not sure if this is the most elegant way, but it does seem to work.

推荐答案

在Dalvik的编译从字节code类/功能到本地机器code,它编译所有的语句,即使是那些在如果的条件。在Android 1.6的虚拟机试图解析(验证) getActionBar 函数,因为没有这样的功能,D​​alvik的抛出的VerifyError

When Dalvik compiles your class/function from bytecode into native machine code, it compiles all statements, even those that are inside if conditions. On Android 1.6 virtual machine tries to resolve (verify) getActionBar function, and since there is no such function, Dalvik throws VerifyError.

您可以做下招:

class ActionBarHelper{
   void setBackground(){
      getActionBar().setBackgroundDrawable(...);
   }
}

...

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

这样 ActioBarHelper 类将仅被编译/验证,当你的SDK正在运行11+。反过来,这将允许调用 getActionBar 不使用反射(反射是另一种可能的解决了这个问题)。函数

This way ActioBarHelper class will only be compiled/verified when you're running on SDK 11+. This will in turn allow calling getActionBar function without using reflection (reflection is another possible solution to this problem).

这篇关于的VerifyError部署在API 1.6的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆