2

Code such as :

    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD)
        ed.apply();
    else ed.commit();

produces a warning in Froyo :

04-27 03:40:35.025: W/dalvikvm(3138): VFY: unable to resolve interface method 219: Landroid/content/SharedPreferences$Editor;.apply ()V

But I understand that in older devices this would be a RuntimeError which would abort the application (see here and here).

So is this way of conditionally calling new API (methods) safe in API 8 (Froyo) and above or there are cases where lazy loading is still needed ?

What changes on Dalvik made this possible ?

Related

Community
  • 1
  • 1
Mr_and_Mrs_D
  • 32,208
  • 39
  • 178
  • 361

1 Answers1

4

produces a warning in Froyo

This is perfectly normal.

But I understand that in older devices this would be a RuntimeError which would abort the application

For Android 1.x, yes.

So is this way of conditionally calling new API (methods) safe in API 8 (Froyo) and above

Yes.

What changes on Dalvik made this possible ?

It no longer "fails fast" when encountering an unidentified symbol, but instead waits to try again to resolve it when the statement is executed. By checking SDK_INT and ensure that the statement is not executed, you don't crash.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • 2
    The change that made it possible was a shift from immediate rejection of a class upon noticing any issue to a mode where some problems are fatal and others result in an embedded "throw always" instruction. This is described in some detail in http://milk.com/kodebase/dalvik-docs-mirror/docs/verifier.html . – fadden Nov 28 '13 at 19:00
  • Beyond using reflection, is there a way to suppress the log warning? – scottt Apr 05 '14 at 07:09
  • So other than using reflection or inner classes, is there a way to suppress the log message? – scottt Apr 05 '14 at 07:15
  • @scottt: You could go "old school" and isolate the new-API stuff in a dedicated class (e.g., the `HoneycombHelper` pattern). So long as you only reference this class from inside a Java version guard block (the `if` test on `SDK_INT`), it will only ever get loaded on a device with the proper SDK level. That should result in getting rid of the warning, at the cost of this additional class and a bunch of static methods on it. It has the side benefit of making you more compatible with Android 1.x. Frankly, IMHO, it's not worth it. – CommonsWare Apr 05 '14 at 09:09
  • Thanks. The call in question is a single WebView setting method(), so isolating it isn't worth the aggravation. The purist in me would like to excise all non-exception warnings and errors from the log, but I can let this one go (along with the "error opening trace file" one). – scottt Apr 05 '14 at 10:31