API Levels

The LruCache class mentioned above is a good example of why you need to know what API level you are going to target. A new version of Android is released approximately every six months, with new APIs only available from that release. Any attempt to call an API that does not exist results in a crash, bringing not only frustration for the user but also shame to the developer. For example, calling Log.wtf(TAG, “Really?”) on an Android 1.5 device crashes the application, as Log.wtf was introduced in Android 2.2 (API level 8). What a terrible failure indeed that would be. Table 1-1 shows the performance improvements made in the various Android versions.

images

However, your decision to support a certain target should normally not be based on which API you want to use, but instead on what market you are trying to reach. For example, if your target is primarily tablets and not cell phones, then you could target Honeycomb. By doing so, you would limit your application's audience to a small subset of Android devices, because Honeycomb represents only about 2.4% as of December 2011, and not all tablets support Honeycomb. (For example, Barnes & Noble's Nook uses Android 2.2 while Amazon's Kindle Fire uses Android 2.3.) Therefore, supporting older Android versions could still make sense.

The Android team understood that problem when they released the Android Compatibility package, which is available through the SDK Updater. This package contains a static library with some of the new APIs introduced in Android 3.0, namely the fragment APIs. Unfortunately, this compatibility package contains only the fragment APIs and does not address the other APIs that were added in Honeycomb. Such a compatibility package is the exception, not the rule. Normally, an API introduced at a specific API level is not available at lower levels, and it is the developer's responsibility to choose APIs carefully.

To get the API level of the Android platform, you can use Build.VERSION.SDK_INT. Ironically, this field was introduced in Android 1.6 (API level 4), so trying to retrieve the version this way would also result in a crash on Android 1.5 or earlier. Another option is to use Build.VERSION.SDK, which has been present since API level 1. However, this field is now deprecated, and the version strings are not documented (although it would be pretty easy to understand how they have been created).

TIP: Use reflection to check whether the SDK_INT field exists (that is, if the platform is Android 1.6 or later). See Class.forName(“android.os.Build$VERSION”).getField(“SDK”).

Your application's manifest file should use the <uses-sdk> element to specify two important things:

  • The minimum API level required for the application to run (android:minSdkVersion)
  • The API level the application targets (android:targetSdkVersion)

It is also possible to specify the maximum API level (android:maxSdkVersion), but using this attribute is not recommended. Specifying maxSdkVersion could even lead to applications being uninstalled automatically after Android updates. The target API level is the level at which your application has been explicitly tested.

By default, the minimum API level is set to 1 (meaning the application is compatible with all Android versions). Specifying an API level greater than 1 prevents the application from being installed on older devices. For example, android:minSdkVersion=”4” guarantees Build.VERSION.SDK_INT can be used without risking any crash. The minimum API level does not have to be the highest API level you are using in your application as long as you make sure you call only a certain API when the API actually exists, as shown in Listing 1–12.

Listing 1–12. Calling a SparseArray Method Introduced in Honeycomb (API Level 11)

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        sparseArray.removeAt(1); // API level 11 and above
    } else {
        int key = sparseArray.keyAt(1); // default implementation is slower
        sparseArray.remove(key);
    }

This kind of code is more frequent when trying to get the best performance out of your Android platform since you want to use the best API for the job while you still want your application to be able to run on an older device (possibly using slower APIs).

Android also uses these attributes for other things, including determining whether the application should run in screen compatibility mode. Your application runs in screen compatibility mode if minSdkVersion is set to 3 or lower, and targetSdkVersion is not set to 4 or higher. This would prevent your application from displaying in full screen on a tablet, for example, making it much harder to use. Tablets have become very popular only recently, and many applications have not been updated yet, so it is not uncommon to find applications that do not display properly on a big screen.

NOTE: Android Market uses the minSdkVersion and maxSdkVersion attributes to filter applications available for download on a particular device. Other attributes are used for filtering as well. Also, Android defines two versions of screen compatibility mode, and their behaviors differ. Refer to “Supporting Multiple Screens” on http://d.android.com/guide for a complete description.

Instead of checking the version number, as shown in Listing 1–12, you can use reflection to find out whether a particular method exists on the platform. While this is a cleaner and safer implementation, reflection can make your code slower; therefore you should try to avoid using reflection where performance is critical. One possible approach is to call Class.forName() and Class.getMethod() to find out if a certain method exists in the static initialization block, and then only call Method.invoke() where performance is important.

Fragmentation

The high number of Android versions, 14 API levels so far, makes your target market quite fragmented, possibly leading to more and more code like the one in Listing 1–12. However, in practice, a few Android versions represent the majority of all the devices. As of December 2011, Android 2.x versions represent more than 95% of the devices connecting to Android Market. Even though Android 1.6 and earlier devices are still in operation, today it is quite reasonable not to spend additional resources to optimize for these platforms.

The number of available devices running Android is even greater, with currently close to 200 phones listed on www.google.com/phone, including 80 in the United States alone. While the listed devices are all phones or tablets, they still differ in many ways: screen resolutions, presence of physical keyboard, hardware-accelerated graphics, processors. Supporting the various configurations, or even only a subset, makes application development more challenging. Therefore it is important to have a good knowledge of the market you are targeting in order to focus your efforts on important features and optimizations.

NOTE: Not all existing Android devices are listed on www.google.com/phone as some countries are not listed yet, for example India and its dual-SIM Spice MI270 running Android 2.2.

Google TV devices (first released in 2010 by Logitech and Sony in the United States) are technically not so different from phones or tablets. However, the way people interact with these devices differs. When supporting these TV devices, one of your main challenges will be to understand how your application could be used on a TV. For example, applications can provide a more social experience on a TV: a game could offer a simultaneous multiplayer mode, a feature that would not make much sense on a phone.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.29.126