23

I've been developing for Android for a few months now, and this question arises again and again: what is the motivation behind addition of completely new features (APIs) to support libraries without them being available in the standard SDK?

Example:

FragmentTabHost API is available only through android.support.v4.app.FragmentTabHost. It is fine most of the time, but if you want to use fragments nesting and PreferenceFragment together, you're dead in the waters - nesting requires you to switch to android.support.v4.app.Fragment (for supporting below 4.2), but there is no implementation of PreferenceFragment in this support lib. As a consequence you either implement custom workarounds, or use third party libraries that have already implemented them (see this question)

Edit: as pointed out by @eugen in his answer, I myself referenced FragmentTabHost from support-v13, which supports native Fragments. However, this information does not change the overall question. In fact, if I would've used this API with fragments nesting, my app wouldn't run on ~30% of devices today (native fragments support nesting from 4.2 onwards).

Example:

Another issue that I encountered today (and wasted too much time on) is with ActionBarDrawerToggle available through android.support.v7.app.ActionBarDrawerToggle. I wanted to use this functionality, therefore I added the entire com.android.support:appcompat-v7:21.0.+ to project's dependencies. I guessed that this will do, but I was wrong - my app did not compile (missing resources referenced by the support library). After trying few tricks from the web, I found this question which finally provided the solution. In short: v7 support library has dependency on SDK, therefore I had to define compileSdkVersion 21.

Consequences:

Now, I tell myself: FragmentTabHost haven't been added to any SDK version yet, which implies that even 4-5 years from now developers will continue to use support-v4 lib for providing this functionality (because even if this API is added today, it will take years before you could safely assume that all target devices support it natively), right? The same argument applies to android.support.v4.widget.DrawerLayout and other APIs present only in support libraries.

If developers bound to use support libraries for years, this also imply that they are bound to experience the above inconsistency/dependency issues long after these issues could have already been resolved, right?

Question:

Why would Google want to keep these libraries forever? Won't it be better for everybody if all the new APIs were added to SDK in parallel to compatibility libs, such that compatibility libraries could age and "retire" at some point?

Edit: following @eugen's answer I'm now puzzled even more - some APIs "evolve" with newer support libs, but do not make it into main SDK (like FragmentTabHost, which evolved from support-v4 to support-v7). What is the reason for not adding them to SDK?

Community
  • 1
  • 1
Vasiliy
  • 16,221
  • 11
  • 71
  • 127
  • 2
    Adding to your point, `RecyclerView` must be accessed solely from a support library. I believe other than the reasons you've already listed, that it may be a way to try to keep the SDK minimal if google can put "extra, non-standard" features in a different library. – MeetTitan Mar 22 '15 at 18:08
  • `FragmentTabHost` did not evolve from anything. There are two separate versions. `support-v4` which handles support fragments and `support-v13` which handles native fragments. **|||** Using support fragments is better because they get fixed quicker. Libraries get fixed often. To fix anything native, Google would have to put out a new version of Android and the fix would be exclusive to that new version. Everybody else would have to use *the support library*. – Eugen Pechanec Mar 22 '15 at 19:18
  • 1
    @EugenPechanec, let me try to explain myself once again. If `FragmentTabHost` for native `Fragment` would've been added to the main SDK instead of `support-v13`, then, of course, some bugs would've been discovered (as with any new API). But these bugs would've been resolved in 1-3 SDK releases, and, starting with Android 5.x (or 6.x, whatever), this API would become stable. Then, few years from that point, any developer wishing to use this API could do this without **any** support library whatsoever. The question is why not add new APIs to SDK **at some point**? – Vasiliy Mar 22 '15 at 19:35
  • 3
    Romain Guy seems to confirm @MeetTitan's suggested rationale of keeping the SDK minimal: http://cyrilmottier.com/2012/07/06/api-16-jelly-bean-review/#comment-840801718. That said, I believe that confining `ViewPager` to the support libraries was a mistake. This widget is too ubiquitous not to standardize. Also it is one of the few real arguments in favor of using a fragment-based design on a mobile UI, and if fragments are in the framework then so should this. Similarly, if `RecyclerView` was indeed designed to eventually effectively replace `ListView`, then it should also be in the framework. – corsair992 Mar 28 '15 at 11:13
  • @corsair992, thx for the link. Though very old, this thread provided a bit more insight into the issue. It seems that many developers asked for libraries, either Google's or 3rd party's. They wanted the existing libraries (like `ActionBarSherlock`), which work well, to be either "promoted" by Google, or maintained by it. While their desire is totally legit, and the reasoning by @RomainGuy about keeping SDK small and not adding components which might "fall out of fashion", this still doesn't explain thy add them to Support Libs... Why not having separate libs for `DrawerLayout` and `ViewPager`? – Vasiliy Mar 28 '15 at 11:31
  • Yes, the v4 support library is monolithic, although the later support libraries are not. The reason for that is likely inertia and convenience as you conjectured in your answer. – corsair992 Mar 28 '15 at 12:25

1 Answers1

7

FragmentTabHost API is available only through android.support.v4.app.FragmentTabHost.

Incorrect. The link you provided leads to android.support.v13.app.FragmentTabHost which (as opposed to android.support.v4.app.FragmentTabHost) works with native Fragments but makes APIs introduced above API 13 available since API 13.

In short: v7 support library has dependency on SDK, therefore I had to define compileSdkVersion 21.

Of course the version 21 of the library needs version 21 of tools and version 21 of SDK. Always use corresponding versions of build tools, compile SDK and support libraries!

As of today these values are recommended:

compileSdkVersion 22
buildToolsVersion '22.0.1'

targetSdkVersion 22

compile 'com.android.support:support-v4:22.0.0'
compile 'com.android.support:appcompat-v7:22.0.0' // includes support-v4
compile 'com.android.support:support-v13:22.0.0' // includes support-v4

Now, I tell myself: FragmentTabHost haven't been added to any SDK version yet, which implies that even 4-5 years from now developers will continue to use support-v4 lib for providing this functionality (because even if this API is added today, it will take years before you could safely assume that all target devices support it natively), right?

Which means that if you implement it using the support-v13 library, you have nothing to worry about. It's going to work as far as API 13.

Read about the difference between support-v4 and support-v13 above.

Why would Google want to keep these libraries forever?

Because you'll most likely want to support older platforms. Which means you need a support library.

Even now you use ActionBarActivity from appcompat-v7 (which was originally intended to backport action bar to API 7) with minSdkVersion 14 because you want that material design backport. This also means you're stuck with support fragments because ActionBarActivity is using them.

Won't it be better for everybody if all the new APIs were added to SDK in parallel to compatibility libs, such that compatibility libraries could age and "resign" at some point?

Support libraries age. You may have noticed that recyclerview-v7 (and other recent android libraries) is available since API 7 and not API 4. And you may also have noticed that RecyclerView is not in the native SDK. Why would you add it to a native SDK making it available only to the newest platform when you can put out a support library making it available for everyone?

Eugen Pechanec
  • 37,669
  • 7
  • 103
  • 124
  • 5
    I think you misunderstood the question. What about `ViewPager`? If I'm only targeting API `22`, I need `support-v4` if I want `ViewPagers`. – nhaarman Mar 22 '15 at 18:39
  • 1
    Thanks for your reply. Indeed I did not notice that there is FragmentTabHost for native fragments (which makes me wonder how comes I used v4 version for my previous app...), but this does not answer the question - why add this to another support lib, but not to the main SDK? In fact, this evolution of APIs in support libs puzzles me even more... – Vasiliy Mar 22 '15 at 18:59
  • @NiekHaarman Yes you do. The same for e.g. `DrawerLayout`. As I said above: Why would you put this inside the SDK? **By putting it in a library you can fix it quicker** and make it available for everyone. Did you see the [Support library changelog](http://developer.android.com/tools/support-library/index.html)? Just now the `DrawerLayout` has changed. `RecyclerView` is constantly evolving. Can you imagine if you would have to make separate adjustments for each platform? *You'd probably have a library for that.* – Eugen Pechanec Mar 22 '15 at 19:11
  • @Vasiliy Because you can't update platform code once it's out. Well, you can, it's called "a new version of android" and vendors are pretty slow at customization and deploying. Having a library allows for quicker repairs, addons and so on. Read my previous comment as well. – Eugen Pechanec Mar 22 '15 at 19:14
  • 1
    @EugenPechanec, I'll try to rephrase - it is totally clear to me why these APIs being introduced in support libs. The question is why aren't they added to SDK **at some point**? Your arguments about making changes apply equally well almost to every feature of SDK itself, but Google does not put any independent set of features inside a separate library, right? – Vasiliy Mar 22 '15 at 19:23
  • Support library is optional.and they can update any time.so we can get new features .it's not good for adding recyclerview in APK when it's in complete funcrional – Asthme Mar 22 '15 at 19:23
  • 1
    Then why not add the [`Switch`](http://developer.android.com/reference/android/widget/Switch.html) to some support library? – nhaarman Mar 22 '15 at 19:26
  • @NiekHaarman https://developer.android.com/reference/android/support/v7/widget/SwitchCompat.html `Switch` backport is in appcompat-v7 from revision 21 i think. – Eugen Pechanec Mar 22 '15 at 19:49
  • @Vasiliy Example: The Action Bar was introduced in API 11/14 and backported via library to API 7. Same for material design from API 21. Same for fragments from API 11 to API 4. The flow goes like this: "It was introduced recently, it's great, this is how we want to do it, let's make that available for older platforms." *Not the other way around.* If there's something everybody could benefit from and is not part of any SDK, let's put it in a library directly (`DrawerLayout`). Understand? – Eugen Pechanec Mar 22 '15 at 19:59
  • 2
    @EugenPechanec, I do understand what you say. What bothers me is the part that you do not address. For example: why Fragments were introduced in SDK as well as in support library, but Navigation Drawer did not make it into SDK? Both are design patterns recommended by Google... The list goes on and on. I suggest we wrap up our discussion and wait to see if we could get another point of view from other community members. In any case, +1 for your insights and suggestions. – Vasiliy Mar 22 '15 at 20:14
  • @Vasiliy **Fragments** No, fragments were *introduced* in API 11 as part of SDK. Many {insert time unit}s later a backport was made available for API 4. If it weren't made, there would be no fragments before API 11, and we'd have to write completely different apps for pre and post-API 11 platforms or include an overwhelming amount of if-then-elses. **Navigation Drawer** Drawer layout was never part of platform code, it was developed to be available for everybody equally since API 4. There is no point in putting it to SDK, because everyone can include the (often updated) library and use it. – Eugen Pechanec Mar 22 '15 at 20:26