MrJ*_*Jre 14 android backwards-compatibility verifyerror android-3.0-honeycomb android-4.0-ice-cream-sandwich
在Android 1.6上部署我的应用程序时,我遇到了向后兼容性问题.我在这段代码上得到了VerifyError:
if(android.os.Build.VERSION.SDK_INT >= 11) {
getActionBar().setBackgroundDrawable(getResources().getDrawable(R.drawable.actionbar_bg));
}
Run Code Online (Sandbox Code Playgroud)
这不是意料之外的,因为在API 11之前不存在getActionBar(),但1.6之后(API 5及更高版本?)根据在API级别上部署时获取的logcat消息进行半优雅的构建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
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
有没有办法优雅地解决这个问题并且向后兼容1.6?
编辑:所以我最终用静态方法创建了一个HoneycombHelper类:
public class HoneycombHelper {
public static void setActionBarBackgroundDrawable(Activity a, Drawable d) {
a.getActionBar().setBackgroundDrawable(d);
}
...
}
Run Code Online (Sandbox Code Playgroud)
不确定这是否是最优雅的方式,但它似乎确实有效.
ina*_*ruk 24
当Dalvik将您的类/函数从字节码编译为本机机器码时,它会编译所有语句,甚至是那些在if条件内的语句.在Android 1.6虚拟机上尝试解析(验证)getActionBar功能,并且由于没有这样的功能,Dalvik抛出VerifyError.
你可以做下一招:
class ActionBarHelper{
void setBackground(){
getActionBar().setBackgroundDrawable(...);
}
}
...
if(android.os.Build.VERSION.SDK_INT >= 11) {
new ActionBarHelper().setBackground();
}
Run Code Online (Sandbox Code Playgroud)
这样,ActioBarHelper只有在SDK 11+上运行时才会编译/验证类.这将允许在getActionBar不使用反射的情况下调用函数(反射是此问题的另一种可能的解决方案).
| 归档时间: |
|
| 查看次数: |
2730 次 |
| 最近记录: |