I have an APK file that contains my application running on a minimum of API 21 so that I can best support material design functions. Since Android Lollipop (API 21) only runs on 12.4% of devices, I naturally want to also support lower APIs. What is the best way for me to create my application with different layouts for both API v21 and less than v21? Should I create two different apps, one optimized for v21 and one for less than v21, or is there an easier way to go about it?
Thanks!
Look, you can create multiple apps & you can use Androids support library.(The Android Support Library is one of the best resources for accomplishing this by taking care of the little things for you).It's always your choice to choose.
You should not build multiple APKs, as this becomes a maintenance nightmare.
Use the Android Support Library and the Android Design Library to take advantage of latest platform features while also backporting to earlier API levels.
This is a common problem for many apps that have design or other optimizations that target newer platform versions (not just API 21+ ... but what about when API 25 comes along?)
There are several factors to consider before making this decision - some programming and some organizational. Android has many features to support backward compatibility within the same app. Resource folders, static methods to check the platform API, compatibility libraries. Some organizations balk at the idea of supporting multiple apps.
Here is a list that you may need to prioritize for your own environment:
Can you limit the resource folders needed to support multiple API's to an acceptable level of complexity? Managing a few additional layouts and/or image folders is pretty easy. But a tight dependency on many layouts for a single Activity or Fragment, and then supporting many screen densities along with device sizes... you may be better separating them into different apps to reduce complexity.
Do you have several nested object dependencies that require determining the device API? If you have layer upon layer of objects that all have different API requirements (Object A is for API 21+, Object B is for API 19 only, etc. and then Object AA is for API 17+ and also depends on either Object A or Object B, depending on the API) - you may be forced into single app development. Or you may be forced into creating libraries and separate APK's so you can properly test your code.
Will the business understand that "single APK" does not mean "cheaper than multiple APK's"? Sometimes dividing the development into separate APKs will reduce complexity and increase development output while decreasing the cost of QA. At other times, they will go through separate release approvals and other "red tape" activities that make separation inefficient. Also, sometimes developers will favor work in "the latest and greatest" API target and quality will suffer in the lagging target API's.
Can you support library or submodule development so that you can reuse code efficiently with multiple APK's? Once you separate the APK's, there may be a tendency to not be familiar enough with each codebase to effectively reuse components. A problem that exists in one APK may get solved without the recognition that is also solves a similar (but not exactly the same) problem in another.
Generally speaking, keeping the same codebase adds complexity with the benefit of maintaining focus on one set of code and keeping management happy. However, specific cases (such as having a notification app - where the very nature of notifications changed in Lollipop) may result in the need to create a new APK at the risk of significantly reduced support for older versions, which may be best as adoption of newer versions reaches saturation.
Google allows you to upload multiple APK's that target different API's (and even devices) for a single app. This is additional flexibility - and additional app store maintenance.
Good luck.
Related
Google allows us to provide newest features on older APIs using Android Standard Library. Google encourages the use of this toolset, without mentioning its downsides.
Are there any like higher RAM or CPU usage, slower rendering or simmilar? Why isnt every new feature added as a part of the library only instead of maintaining 2 separate versions? Almost every example and real world code I saw had to use this library in order to support ActionBar and other things, so we can assume 90+% applications depend on it. Why not just force it?
There are no known obstacles of using support library. Moreover as you rightly noted, Google encourages to use it as best practices:
"Including the Support Libraries in your Android project is considered a best practice for application developers, depending on the range of platform versions your app is targeting and the APIs that it uses." (http://developer.android.com/tools/support-library/index.html)
As a disadvantages we can mention just few minor things:
increasing of apk size and total number of methods in project (very insignificant in comparison with other functional costs)
some specific limitations of use (usually they are mentioned in corresponding Java docs and they usually don't play any role if we use in app only support implementation without mixing them with 'native' elements from sdk). As an example see the FragmentActivity class, 'Known limitations' section.
As for your second question - a great amount of new features are included just in support library avoiding duplication in core SDK (android.support.v4.view.ViewPager and android.support.v4.view.PagerAdapter as an example).
Duplicating features (such as Fragment) are preserved to keep the compatibility for apps which were designed using native implementation.
As far as I know, support library is using because old devices don't have new APIs. For example they don't know what Fragment is and how to implement it. Therefore, these behaviors are defined in support library.
So, my main question is, what is/are difference(s) between library of Fragment in support library with its twin which is introduced in API 11 (Android v3.0, Honeycomb).
My second question is, If its possible to put every new API in support library, why we have two types of libraries? I mean Android can release all APIs just under support library rather than support library and Android version X.xx library.
As far as I understood, support libraries may work as alternative of built-in APIs, but they are not supposed to be, because they directly effect the size of the application.
For example, a support library is of 2MB, and to use its functionality, it takes all classes, resources, etc (of 2MB), so now classes.dex (Dalvik executable file of all classes being used in application) of my application also include that support library classes, and same for resources. So, if without support library my app size was 1MB, then now with support library the size is 2MB extra, which means 3MB total.
Now, suppose this support library feature is so common that on single device, if I have 10 apps, then at least 9 are using this same support library, so 9*2 = 18MB on my device is being used by the same support library, which is repeated in every application, which is bad, because for now 18MB might not be so much, but the space required can increase, if you have more applications using that support library.
Thus, the best option is to have that 2MB support library already in your OS for any number of apps, instead of having it for each application. So, support libraries are meant to be used when you really want some efficient features in your app to support older versions.
Another question arise here:
why not this support library is added to the OS as its own update, so that every app without size problems can access that functionality?
The answer is that there could be a lot of errors. Suppose some user doesn't have that update (support library) installed...
There is also the chance that as an update, it may not work as efficient as supposed to be, or may cause problems while integrating with the OS, as we already seen that each OS (windows, Linux, mac) comes with new versions, instead of just giving updates for life time for all new features.
Android 4.0.x (ICS) has a lot of added features compared to lets say Android 2.3.x (Gingerbread). The compatibility libraries are there to bridge some of those changes that were added to ICS that -could be- supported by Gingerbread. "could be" being the key phrase here because there are a ton of changes made to ICS that would never work with Gingerbread and those, of course, will not get a compatibility library.
Fragments for example, which you brought up, are actually done slightly different in ICS than in the compatibility library because ICS has more features it can use. If you look at the code for ICS for the Fragments class, they are not the same as those in the compatibility library. Its a whole second set of code to make something "like" the Fragments in ICS be used in an older version like Gingerbread without the programmer noticing much difference.
That is the point of compatibility libraries and the reason why they aren't used to extensively patch Gingerbread to use all of the features in ICS (they just can't). The point of the compatibility libraries is to interface things available in newer versions of android such as ICS, done the ICS way into older versions such as GB, done the GB way.
As far as why they don't just keep the support library growing and leave the same base OS -- the answer to that is compatibility issues. If a user only has v4 and v12 is out, what happens? Android right now uses the Android API version of the OS as a basis for application compatibility and developers have an option to include support libraries (increasing file size of their app, but giving them newer features). Every application that uses support libraries, independently includes them (meaning 4 apps = 4x included).
The idea is, you may only download apps supported by the current API version of your OS (as far as Google Play is concerned) and you may choose to include support libraries to keep the look and feel of your app supported for older APIs, that do not yet have features that you elect to have available for those users on newer APIs. It's really a look and feel consideration more than anything else.
Hope that clears things up :)
What has been said already it is true. Although there are some details missing.
In fact, I had the chance to attend to a session in the last Google IO where they specially talked about that.
It was actually surprising for me to get to know that support library doesn't host the code for all the posible API versions, rather it's an adaptation of the new features which they think are relevant enough to make them available to older platforms. So the way it works it is generally the following:
Let's say we need to use the brand new (available from API 16) ConnectivityManager to keep track of network changes
We include support libraries v4 and we use the class
The way it works after is that the system will check our API version and will run built-in native code in case we are in API 16 or will run the code of the support library in any other case.
So it's acting like some kind of route gateway. Reason being is that it's generally more efficient (and performing) to use the last code optimized for the last OS and the last system improvements (ie.: hardware acceleration).
Nonetheless there are some elements that weren't translated to the compat library as they are in the native built-in code. For instance fragments weren't meant to be re-written as they are from API13 since they are a huge component that need to run in a wide range of different scenarios within system and devices with less capabilities.
Ultimately and because all this, it is recommended to use compats libraries which is known as a good practice, specially if you intend to make your apps / code available for older versions (which should be the ideal way)
The support library does not in fact have everything that is in the newer APIs. It does support parts of the Fragment API, but it does not yet support ActionBar. For that you need another library like ActionBar Sherlock.
Why are there two libraries?
Because part of the problem was Google only back ported some of the stuff, but my understanding is that, additionally, some of the new functionality can't be back ported due to core OS framework limitations and missing APIs deep in the core of the Android UI framework.
Android came up with cool features of fragments and action bar in recent releases.
Now if we want to use these features and also support older version of android then we will have to write highly messy version dependent code, which is not good.
To save us from all these mess, android came up with support library which does not provide full support of new features but is good enough to allow developers to write neat code which is supported on all devices.
Answer to your second question is very simple, fragments are integrated part of v3.0 and if you want you application to run only on v3.0+ then you really don't have to include external library.
Fragments from Support library equivalent to fragments of Honeycomb+.
To second quest, from documentation:
v13 is a superset of v4 and includes additional support classes to work with v13 APIs
ie the same functional, just adapted to v13 API.
I am use modified v4 support library - with maps.
I'm planning on writing an app and building against 2.2 Froyo (API Level 8). However, I want app users of 4.0 ICS to experience the app with the ICS user interface.
Currently my approach is to have the default activity of my app sense the version of the Android device.
If it is less than 4.0, use XML views written for Gingerbread and Froyo and, if it's 4.0 or higher to use ICS XML views. This however seems a bit haphazard and I'm not sure I can manage the separation of version views effectively.
What approaches, tools, and ideas can I use to help me make my app? Is it even something I need to consider? Is my idea of the view separation above correct? Do I have alternatives I could use instead?
Cheers!
If you just want to apply different resources for different OS version, you can let system do it for you by putting your resources into different resource folders with the "v" qualifer. Such as "layout-v8" folder for layouts used for Froyo and "layout-v14" for layouts used for ICS. I did not try this but from the document, that's what it supposes to do.
The Crunchyroll app (an anime viewer) has separate activities and layouts for Froyo vs. Honeycomb/Google TV, defaults to one or the other on initial startup, and thereafter allows the user to declare a preference for one or the other. I'm not affiliated with CR, but I use and have studied the app. One problem the app has, which may be encouraged by the level of separation it has between the two targets, is that the pre-Honeycomb interface has many features, and continues to receive updates, that the tablet/TV interface is only promised.
As for tools, you can use later features while targeting an earlier OS with the SDK's support package, which backports features (e.g., fragments) appropriately.
I have a published app for Android 1.x and 2.x, and now I want to make it support 3.x.
But Android 3.0 has massive API change, especially on UI, thus if I want to make one app compatible to 2.x and 3.x, the code will be ugly and package file will be huge.
On the other hand, if I make another app for 3.x, then I need to maintain two copies of their common codes. That's really annoying.
What should I choose, or does anyone have a more smart solution? Thanks!
If you package them together you could still maintain everything separately - For example: put a prefix in front of every layout and class for 3.x, such as honeyMain.class, and honeymain.xml
Or you could do it a way that makes more sense for you.
Or keep them partially together.
It WILL make your app larger, but then when 15 people with 3.x download it and 60 people with 2.x download it, you get 75 downloads, instead of 15 for one app and 60 for the other. The 75 cumulative will look better on the apps over all ranking on the market.
On the other hand, if the 3.x is really ugly or FCs, then negative ratings will impact both 2.x and 3.x, but that is easily controlled for by testing, testing, testing.
Also, I personally hate managing code for two different apps. It's overly repetitive.
So, my recommendation is to package them together.
Make use of resource qualifiers, e.g. -xlarge, -v11, etc.
Use reflection where necessary or other techniques to avoid pulling in stuff not supported by API level.
Use the compatability library, that way you can fragmentize your code regardless, avoiding duplication, and with little effort handle different screen sizes.
See providing resources
See multple screens
See compat lib
Right click on your project and select "properties",select "android" from window,and which type of version you want check it and apply
I have a project that is just using Android 1.5 for programming, but with the proliferation of other handsets and some cool features in Android 2.2, we'd like to support the features without losing support for 1.5 or forking a new code base. Is it possible to do with Android SDK?
I do have some sense of the "ugly" way to do it, as in keeping the same code base but have a build system that builds different versions for the platforms and keep different Java files around that get added in our out of the build based on which version is selected. I'm hoping someone else has solved the problem based on the many versions of apps in the market that run on multiple Android versions.
we'd like to support the features
without losing support for 1.5 or
forking a new code base. Is it
possible to do with Android SDK?
Sure. The techniques have been around for about a decade or so.
Option #1: Use reflection to access new classes (or new methods of existing classes) at runtime. See here for an example.
Option #2: Use conditional class loading, by creating an interface plus two implementations (one for an older API, one for a newer API), and loading the right implementation at runtime. Since the newer implementation will not be loaded on a older device, the fact that the newer implementation uses classes or methods that the older device lacks will not pose a problem. See here for an example.