android低版本api在高版本系统,【转】关于android需要用到高版本api导致低版本手机出现VerifyError的问题...

没事就逛逛eoeandroid的问答区帮忙解答问题,碰到了一个以前我也碰到过的问题,这里写下做个笔记吧。

问题如题目所说,就是需要用到一些在比较高的版本中才会出现的api,那么呢,低版本中显然是不能用的,我们需要先判断当前的sdk版本然后确定要不要用这个api。

然后呢,理所当然的,我们会用if语句控制一下,比如:

1

2

3

if(android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.DONUT) {

overridePendingTransition(0,0);

}

或者

1

2

3

4

5

6

int version=android.os.Build.VERSION.SDK_INT;

if(version>=8){

DownloadManager dm=(DownloadManager)getSystemService(this.DOWNLOAD_SERVICE);//2.3新增的

DownLoadManagerUtils dmu=new DownLoadManagerUtils(this,dm,apkURL);

dmu.setData("com.benesse.memorandum", "下载中...", true, true, "mydownload", "abc.apk");

}

或者

1

2

3

if(android.os.Build.VERSION.SDK_INT >= 11) {

getActionBar().setBackgroundDrawable(getResources().getDrawable(R.drawable.actionbar_bg));

}

上述代码都来自网上,做个借鉴而已。

看起来我们用if语句判断,如果版本不够的话是不会执行的,可是呢,实际上会出现:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

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

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)

这种错误,这个是怎么来的呢?

StackOverflow.com上有人这么解释:

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.

其实也就是说虚拟机在load类的时候并不只是一些静态的东东会初始化,**有些方法,就算在if里面,也是会检查(verify)一下的,一旦发现没有这个api,那么就会报错了**。

所以呢,一般我们使用内部类的方式来解决这个问题。内部类的话,就不会深入的verify了,只会在运行时执行这些代码了。

例如第一个对应:

1

2

3

4

5

6

7

8

if(android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.DONUT) {

new Object() {

public void overridePendingTransition(Activity c, inti, intj) {

c.overridePendingTransition(i,j);

}

}.overridePendingTransition(this,0,0);

}

第三个可以这么写:

1

2

3

4

5

6

7

8

class ActionBarHelper{

void setBackground(){

getActionBar().setBackgroundDrawable(...);

}

}

if(android.os.Build.VERSION.SDK_INT >= 11) {

new ActionBarHelper().setBackground();

}

反正就是合理利用内部类(不管是不是匿名的)来避免装载时检查出现这个问题。到了运行时,通过if来阻断不合格的api被执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值