One of the better ways to dive and and get to know any complex software system is to take code previously written against an older version of an application and port it to the latest release of a compiler, software framework, operating system, or other complex software environment. Every complex system provides code examples to illustrate features and capabilities and to act as a starting point for other developers. And every example is always written against the earliest release, and more often than not, is never revisited and brought up to date against the evolving compiler, software framework, operating system, or other complex environment.
In order to advance and still allow older written software to continue to work, some systems (such as Java) will publicly deprecate a given interface but still allow it to be compiled with older applications so they can continue to work. Ideally as a developer you're supposed to note the deprecation warnings that come from a compiler (command line) or integrated development environment (IDE) and to correct them. In a dynamic and evolving software environment public interfaces can become deprecated because the creators discover better functional and/or faster ways to deliver a service behind the interface. Creators always (mostly) try to add value with an existing interface, but when that's not possible, the older interface is deprecated, a newer better one is created, and documentation is updated to point out how to use the latest interface that replaces the deprecated interface.
Of course, the question is always asked, "When is the deprecated interface dropped completely?" And the answer, unfortunately, is usually "Never." The motivation to use the newer interfaces isn't that older interfaces will be dropped, but that no further work will be done on older interfaces. All the development and bug fixes go towards the latest and greatest. Old and deprecated is allowed to rot. And if you don't update your software, it suffers from that internal bitrot.
In the example above I opened one of the early Android projects, NotesList. This is part of the collection of example applications that are delivered with the Android SDK. I created a new project with NotesList, and started to open the source files and look at the warnings generated within Eclipse. One of the deprecated warnings was against android.app.Activity.managedQuery(...). That deprecation forced me to replace one line of code with four, using the following recommended steps:
CursorLoader cursorLoader = new CursorLoader(this.getApplicationContext()); cursorLoader.setUri(mUri); cursorLoader.setProjection(PROJECTION); mCursor = cursorLoader.loadInBackground();
The key being the replacement of managedQuery(...) with essentially CursorLoader.loadInBackground().
It took several attempts to find the exact invocation for the creation of a CursorLoader instance. The Android documentation was a bit vague as to correctly obtain the correct argument. My first creation of a CursorLoader was new CursorLoader(this). It compiled just fine and the emulator even started up, but after several moments of testing the emulator core dumped (crashed). I went back and re-read the Android SDK documentation a bit further and on a hunch (or guess, take your pick) created new CursorLoader(this.getApplicationContext()), which is what the documentation was trying to ask for. It was interesting that the bare this reference was accepted as a type of ApplicationContext, or at least the IDE issued no warnings.
In any event it worked and I've been "fixing" other deprecation warnings. The only problem with just blindly fixing deprecation warnings is you miss the bigger design picture. APIs are created and used in a larger architecture and design context. Just because I fix the warnings doesn't mean that their use is now considered best practice at this point in time. Keep in mind that Android first started as an OS purely for handsets. Then, starting with Android 3 (Honeycomb), Google started migrating to tablets. The migration wasn't complete until Android 4 (Ice Cream Sandwich) and beyond. Some best practices for handsets didn't transfer all that well to tablets. That's why Google refused to release the code for Honeycomb; Honeycomb was a right royal hack with bad API juju all over the place to support the initial sale of Android tablets such as the Motorola Xoom. Google wanted a chance to release new and updated public APIs with decent implementations that were worth supporting in the future before they turned the code completely loose.