Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android backward compatibility but still utilise latest API features

I have noted in the Android Market that many popular applications have backward compatibility to much earlier versions of Android. E.g.

Evernote - 1.6
Faceobook Messenger - 2.2

These applications look and work great but how can they do this and support much older API levels? Are they only using API features that exist in the lowest supported OS version, hardly? I'm assuming they must be using some features of the later API levels to provide a great UI and featurelist.

I can see two possible solutions:

Use Min/Target API levels in build. Then through code you check the OS version and implement the features using a supported method and degrade gracefully. This seems like a lot of work.

Have multiple app versions targeting various OS versions. E.g. A release for 2.2 and another for 4.0. Is this possible?

The reason for asking is I am planning a new app that should support 2.2 but I fear I may require API features that are only available in later releases? Should I just target 2.2?

EDIT: Also, what role do Compatibility Libraries play? Is this the key?

Thanks.

like image 609
jim Avatar asked Sep 04 '12 22:09

jim


2 Answers

We (Evernote) do extra work to support 1.6 and use as many new API's as we can. The main problem with supporting 1.6 is that Dalvik does a greedy search on your classes. This makes it impossible to use code like

if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
    prefEditor.apply();
} else {
    prefEditor.commit();
}

Because it would throw a class verification error. This is caused when dalvik sees your method and tries to access it at runtime.

Instead you need to use a helper class to instantiate the appropriate class for the SDK. Yes this is much more work

public abstract class SharedPreferenceEditor {

  private static SharedPreferenceEditor sInstance;

  public static SharedPreferenceEditor getInstance() {
    if (sInstance == null) {

      /*
      * Check the version of the SDK we are running on. Choose an
      * implementation class designed for that version of the SDK.
      */
      @SuppressWarnings("deprecation")
      int sdkVersion = Build.VERSION.SDK_INT;
      if(Evernote.DEBUG)Log.d("SharedPreferenceEditor", "sdkVersion=" + sdkVersion);
      if (sdkVersion < Build.VERSION_CODES.GINGERBREAD) {
        sInstance = new CommitSharedPreferenceEditor();
      } else  {
        sInstance = new ApplySharedPreferenceEditor();
      }
    }
    return sInstance;
  }

  public abstract void save(SharedPreferences.Editor editor);
}

Then you have one for the gingerbread + api level

public class ApplySharedPreferenceEditor extends SharedPreferenceEditor {
  public void save(SharedPreferences.Editor editor) {
    editor.apply();
  }
}

and one for the < gingerbread level

public class CommitSharedPreferenceEditor extends SharedPreferenceEditor{
  public void save(SharedPreferences.Editor editor) {
    editor.commit();
  }
}

I'd recommend supporting 2.1 and up so than you can take advantage of the improvements to Dalvik and use the first example I listed.

like image 198
tsmith Avatar answered Oct 05 '22 19:10

tsmith


There are a few different strategies for mixing backwards support with the latest features. There's lots of references within the Android documentation, but maybe start here: Backward compatibility for Android applications.

But in general, I would strongly recommend you avoid publishing multiple versions if possible. Use your app's manifest to target a suitable range of OS versions and code accordingly.

And yes, there's also the standard Android Support (Compatibility) Library. Generally the purpose of the compat libraries is to allow your app to use some of the latest OS features while providing some comparable implementation for older platforms. You should definitely look into this.

There's also a few great 3rd party compatibility libraries. Here's a few I've used in my projects and definitely recommend:

  • ActionBarSherlock
  • NineOldAndroids
  • HoloEverywhere

Note that NineOldAndroids is actually included within ActionBarSherlock.

like image 20
newbyca Avatar answered Oct 05 '22 19:10

newbyca