I feel I have some questions about using support libraries. Having started developing some months ago, I am facing the situation where all of my targeted devices (let's say API>16) have pretty good and consistent tools, smart enough to fit my needs, but really miss some UI elements in comparison with API=21.
Today I added three new dependencies from the v7 support libraries. What I've noticed is that, as expected, the app size lifted from just 200kB to 3800kB. While that does not really make me worried, I can imagine that, along with size increasing, the smoothness of a process relying on dependencies can be reduced. And I went for v7 for purely graphical wishes.
I'm wondering: is it convenient to rely on support libraries if not strictly needed? Is it reasonable to add size and lose some smoothness, just to bring Material to, say, >4.2 users? Would it be better to have separate styles and take some (sometimes hard) work to emulate new features on older OS versions?
(note that the goal here is maximizing the popularity of the app).
As a consumer myself, I'd go for the best looking UI, but only if the app runs as it should. In addition, the older the device (and we're talking about older devices here), the more concerned should the user be about size and smoothness, as his hardware would be dated.
P.S.: I don't think that 4MB is a troubling size - I'm asking for some kind of "rule". Plus, I've read here, and I feel my question could be "constructive", although secondary. Feel free to flag it if it's not.
Using any library is a shortcut to doing all the work yourself - if you find it more efficient to pour over the design guidelines, implement , and test on many devices and many API versions, then do so. For many, the easier choice is to use the Support Library.
For APK size and 'smoothness of a process', Google provides two tools minification (via ProGuard) and resource shrinking as per this Google+ post announcing their availability. Assuming you are using Android Studio and Gradle, you can add:
android {
buildTypes {
release {
minifyEnabled true
shrinkResources true
}
}
}
Which will strip out unused methods (the minifyEnabled part) as well as unused resources (the shrinkResources part). This can be especially helpful with libraries such as the AppCompat Support Library which contains a number of image resources that you may not actually use in your application.
Obviously, the minification/shrinking process takes some time and can slow down your development process hence why they are only enabled in that example for release builds.
I would definitely recommend using the support libraries. We use them on our commercial app and we do not get complaints from users with older devices. But because we use them we are able to move very quickly to adopt new Android features, many of which would be extremely difficult to implement ourselves. Especially with Lollipop, Google is making it harder to just imitate the UI.
I was going to add some comments about ProGuard, which I also recommend, but Ian's answer has some great suggestions along those lines, so I will leave it at that.
Related
I am building some android application. And of course it use many library included in gradle.
I want to do performance test, which library can affect much my application performance for doing other logic , like encode and decode, or other stuff.
Any idea?
There's an entire section in the Android User Guide called Profile Your App. There's a number of tools you can use to measure the performance of your app, however an extensive performance testing will probably be time consuming. Normally you'd have to identify a problem in your app and pick appropriate profiling techniques to find out what causes it.
To add to #Egor's answer about profiling, you may also want to think about the method count limit when considering library dependencies, in particular on older devices. While not directly related to runtime performance, having to use multidex in your builds will significantly increase your build times and the initial loading time of your app (on Android older than Lollipop).
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.
So, in order to support ActionBar on Androids < 4, I had to include the appcompat-v7 library. This library adds quite a bit of overhead in form of code and images (~600KB).
So I was thinking I might change the project a bit and generate separate packages, one for androids < 4 and one for newer androids. This should not be hard since the appropriate imports and definitions are only in a few source files (<5)
Subquestion: is it even worth the bother given that the only perceived gain is reduced package size?
Anyway, since this requires a modification in build.gradle, is this even possible?
How can I make this work? Naturally, when debugging, Android Studio should "know" what flavor to build when deploying to appropriate emulator (even if it's always the one with appcompat). I don't want to have to work more because of this.
Sorry this is an older question, but I came across it while googling something similar. I found this great blog that answered a lot of my questions about flavors, and how to use them: http://blog.robustastudio.com/mobile-development/android/building-multiple-editions-of-android-app-gradle/#comment-940
In your circumstance, however, I wouldn't use flavors. I would instead use a support library: http://developer.android.com/tools/support-library/setup.html They will allow you to use cool new features of modern Android OSes without your users actually having that version. Good luck, and I hope this was still relevant!
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 would like to add two versions of my app to the Android Market, one for a few cents, and one free version, with ads. That's a very common practice.
I'm currently building AdMod into my app, and it seems I'll have to change quite a few files, so it seems best to make a separate version of my app for this.
How do you achieve that? A branch? A different repository? Has anyone found a way to keep both apps in the same repository in a reasonable manner?
The title is not misspelled, I do mean "realise", i.e. how people manage the two versions, not how they add them to the Market.
This kind of thing is a complete nightmare - unfortunately the Android build system doesn't really support it in any good way.
We do it by having 99% of the code of our application in a library project. We then create one application project for each different version of the app, each of which use that library.
Where we need different versions of the app to behave differently, we currently achieve that by having different resources that are queried at runtime. We are in the process of moving to using Dependency Injection via RoboGuice, however.
There are elements of this that work reasonably well, and others that don't. It's necessary, for example, to duplicate the AndroidManifest.xml file, which can be error-prone (it's easy, for example, to add a new activity to one manifest and forget to do so in the others). It's a mess, unfortunately, but the least-bad solution we've found.
Personally speaking, I would strongly advise against using branches to achieve this effect. They can work well initially, but will rapidly become a maintenance nightmare.
One side benefit of using a library is that we've found that it makes testing considerably easier. For an example of how to set this up, see:
http://www.paulbutcher.com/2010/09/android-library-project-with-tests-step-by-step/
People usually upload them twice(like two different programs) and just modify the title for adding something like Ad-Free, Donate and things like that. And on the free version just add the Free label and also put on the description that it's Ad-Supported.
Here is an example with the SMS Popup application:
For the Android Market, they are considered different programs, but for us it's the same, but one is Ad-Supported and the other isn't.