Versioning in Android is critical to identifying capabilities and age of the application. Like many other software components, Android applications are automatically handled by services (such as the CI) or manually managed by persons (such as the QA or PO). While the Android system uses a simple numerical versionCode to protect against downgrades of applications, services and persons mostly rely on the versionName defined for the application. This versionName can be any string and the Android system doesn’t enforce any constraints on it. For human and machine readability, Semantic Versioning should be considered though.
The versionName is part of the Android manifest, but it’s usually defined for all build variants within the build.gradle script of the application. Here it’s possible to declare a versionCode, a versionName and a versionNameSuffix. …
RecyclerView.ViewHolder describes an item view and metadata about its place within the
RecyclerView. Also it is responsible for caching potentially expensive
View.findViewById(int) call results. In combination with the same synthetic properties that provide access to layout specific views of activities and fragments, this is basically the purpose of the Kotlin Android Extensions
A base interface for all view holders supporting Android Extensions-style view access.
ViewHolder and the
LayoutContainer in one type, provides a powerful tool for all
RecyclerView.Adapter implementations with Kotlin.
open class SyntheticViewHolder(
override val containerView: View
) : ViewHolder(
The main advantage here is, that the
ViewHolder itself handles the caching of the views and does not know about the structure of the view or the items bound to it. …
Useful documentation for any lambda: (foo: Bar) -> Unit
Function declarations contain names for their parameters. That’s as ordinary as it gets in programming.
The definition of anonymous functions and lambdas contain named parameters, though
it might be implicitly named and used with lambdas. Depending on the context of the function or lambda declaration, there might not even be any need to declare the parameter type.
When it comes to declaring the type of the function itself, the focus is on the type. Thus a common declaration is just
(Int) -> Unit, a function expecting a single parameter of type
Int. Knowing the context of this, it should be fairly easy to figure out the meaning of
it later. But even with only one more
Int parameter, the purpose of each would become arbitrary at once. …
Support for the Maven Publish plugin has landed in Android Studio 3.6. Unofficial implementations have been around with android-maven-publish or the abandoned android-maven-gradle-plugin. But these tools rely on internal Gradle APIs and thus have to be updated with every new release of the Android Gradle Plugin or Gradle itself.
The Android Library Plugin now creates an adhoc-component named all and one for every single build variant. These components are the basis for the Gradle publishing publications and provide a simple interface for extending these with other artifacts. The variant components declare a single library artifact publication, while the all component declares all maven dependencies as optional and differs in the definition of Android configuration attributes. In addition to the standard Gradle ones, it also provides attributes for the Android variant, the build type and the product flavors. …
No, it is not clear how to achieve this task. An SDK might help with what you expect it to, within your product and often many more things. It is not a magic wand, performing any task by itself just by adding a reference and calling an initialisation method. Even though there are SDKs and use-cases for which this might hold true, yours does not necessarily fit into this category. An SDK is merely a tool box which has to be used actively.
As with any other task it’s always good to describe the problem first. Your developers might already know of different, or even better, approaches to a solution. The SDK might not even provide any means to solve the problem at all nor hold the only feasible approach. Now the problem itself is an ideal measurement for acceptance and verification of the task and the actual implementation of it. …
When developing an application, the two build-types debug and release are defined by default. Additional to these two and possibly some other custom ones, different flavors of the app can be defined with multiple dimensions. To differentiate between these, the version or application name should be annotated with a suffix or replaced completely. Furthermore, the app could change its state dynamically on runtime, like switching between staging and production environments.
In most of these cases though, all these app configurations appear alike when being run on the device. Some relevant information might be accessible within the settings or on info screens. While developing or testing the app, this information being displayed as an overlay to the layout of every single screen, and therefore even more accessible, could increase the efficiency in day-to-day work tasks. …
The struggle is real. To improve on build speed, Android projects modularize into many small sub-modules. Some of these might be pure Java or Kotlin libraries, not concerning themselves with the version of the Android framework. But every Android application, library or feature module should be configured to target and compile with an identical Android SDK version. The most common way to achieve this with the least effort is to define the versions once in the root project, and then referenced afterward within every other project. The extension container for
project.ext helps with it.
ext.versions = [
Occasionally our app started crashing for some of our users, while on first sight the code looked just fine. But our analytics suggested otherwise. From Firebase it was hard to figure out, how this all could have happened. We’ve just had enough information to figure out, on which screen the error occurred. But that’s about it. Thanks Rx!
All started after replacing the generic call to
notifyDatasetChanged() with an implementation of
DiffUtil and therefore calls to all the other members of the
notifyItem*() family of callbacks. …
Generally you’ll find phrases in the JitPack Android documentation like:
Check that you have the Gradle wrapper in your Git repository. […]
But what exactly is a Gradle wrapper?
Most tools require installation on your computer before you can use them. If the installation is easy, you may think that’s fine. But it can be an unnecessary burden on the users of the build. Equally importantly, will the user install the right version of the tool for the build? What if they’re building an old version of the software?
The Gradle Wrapper […] solves both these problems and is the preferred way of starting a Gradle build. …
When I started working on our app, I took over an application which was merely an architectural skeleton. Different layers were defined already, as well as dependencies included to work on this given stack. This comprised a dependency to an extensional utility library with dependencies on other smaller libraries and parts of the Android Support Library with a fixed version. In the end we only needed and used a handful of these utility classes, but got all of the other classes and dependencies for free as well.
Like maybe many other Android developers, I object to bloating my libraries and applications with too many dependencies; even though Proguard gets rid of most of these for production builds anyways. Naturally I tried to replace the given behaviors with other implementations, being able to reduce and remove the out of scale dependencies. Then I started wondering, how to solve this issue. Adding modularity like Google did with the Android Support library is a good start. Depending on the library itself, may be overhead as well. Especially when most of the sub-libraries are pulled in separately at once, it does not make any difference. …