About This Series
This “Android Kotlin Basics” blog series is all about fundamentals. We’ll take a look at the basics of building Android apps with Kotlin from the SUPER basics, to the standard basics, to the not-so-basics. We’ll also be drawing comparisons to how things are done in Kotlin vs. Java and some other programming languages to build Android apps (like C# and Xamarin or JavaScript/TypeScript for Hybrid implementations).
Check Out the Pluralsight Course!
If you like this series, be sure to check out my course on Pluralsight – Building Android Apps with Kotlin: Getting Started where you can learn more while building your own real-world application in Kotlin along the way. You can also join the conversation and test your knowledge throughout the course with learning checks through each module!
Watch it here: https://app.pluralsight.com/library/courses/building-android-apps-kotlin-getting-started/table-of-contents
Kotlin Package Level Functions and Members
So, Kotlin is an object-oriented language, however, it is not exclusively an object-oriented language. What does that mean? You can actually use Kotlin in a completely functional way and not require any of your implementation to be encapsulated within interfaces
and classes
. In Kotlin, you can define code within functions and property/variable members from the package level! This may be a weird concept for those coming from an exclusively object-oriented background, and especially from Java, but luckily, Kotlin simplifies so much of this confusion and makes it really simple to use back and forth.
In the last Android Kotlin Basics, we looked at static classes and functions, but Kotlin actually suggests using package level functions rather than companion objects or regular objects when needing simple static methods.
How does this work? Well, the name sort of speaks for itself! These are functions and members within a Kotlin file, but not class. Then they belong to whatever package you declare the file belongs to, OR, to the entire root package if you don’t specify one at all.
Here’s what that looks like:
HelperFunctions.kt
package com.suavepirate.helpers // this is a file with random functions that belong to the package above. fun sayMyName() { println("Alex Dunn - Suave Pirate") } fun isThisTrue(trueOrFalse: String){ return trueOrFalse == "true" ? true : false } val bestLanguageForAndroid: String = "Kotlin"
Now we can use these functions in three different ways:
- Import each function / member
- Import package with wildcard
- Reference each call with the package name
MainActivity.kt
import com.suavepirate.helpers.sayMyName import com.suavepirate.helpers.isThisTrue import com.suavepirate.helpers.bestLanguageForAndroid //... other packages // showing how to use these functions and members with the import class MainActivity : Activity() { override fun onCreate(savedInstance: Bundle) { sayMyName() val isTrue = isThisTrue("true") toolbar.title = bestLangaugeForAndroid } }
With the wildcard import:
MainActivity.kt
import com.suavepirate.helpers.* //... other packages // showing how to use these functions and members with the import class MainActivity : Activity() { override fun onCreate(savedInstance: Bundle) { sayMyName() val isTrue = isThisTrue("true") toolbar.title = bestLangaugeForAndroid } }
Or without using the package import:
MainActivity.kt
//... other packages, but not the one where the members live // showing how to use these functions and members without the import class MainActivity : Activity() { override fun onCreate(savedInstance: Bundle) { com.suavepirate.helpers.sayMyName() val isTrue = com.suavepirate.helpers.isThisTrue("true") toolbar.title = com.suavepirate.helpers.bestLangaugeForAndroid } }
This allows us to use these members and functions in either a static way, or in a functional way if your entire application wanted to focus more on that pattern over object-oriented! Kotlin gives us so many options!
But what about using this pattern when mixing Kotlin and Java? Underneath the hood, the Kotlin compiler will actually create a class
for the entire package that wraps all of the members and functions within it. This means that in Java, we can use it in the exact same way! It then uses the naming convention of {PackageFinalName}Package
MainActivity.java
import com.suavepirate.helpers; //... other packages // showing how to use these functions and members with the import public class MainActivity : Activity() { @Override void onCreate(Bundle savedInstance) { HelpersPackage.sayMyName(); Boolean isTrue = HelpersPackage.isThisTrue("true"); toolbar.setTitle(HelpersPackage.bestLangaugeForAndroid); } }
Jetbrains themselves have a great post on some greater detail about how this works: https://blog.jetbrains.com/kotlin/2015/06/improving-java-interop-top-level-functions-and-properties/
If you like what you see, don’t forget to follow me on twitter @Suave_Pirate, check out my GitHub, and subscribe to my blog to learn more mobile developer tips and tricks!
Interested in sponsoring developer content? Message @Suave_Pirate on twitter for details.