This topic focuses on some of the most useful aspects of the Kotlin language when developing for Android.

## Work with fragments

The following sections use`Fragment`examples to highlight some of Kotlin's best features.

### Inheritance

You can declare a class in Kotlin with the`class`keyword. In the following example,`LoginFragment`is a subclass of`Fragment`. You can indicate inheritance by using the`:`operator between the subclass and its parent:  

    class LoginFragment : Fragment()

In this class declaration,`LoginFragment`is responsible for calling the constructor of its superclass,`Fragment`.

Within`LoginFragment`, you can override a number of lifecycle callbacks to respond to state changes in your`Fragment`. To override a function, use the`override`keyword, as shown in the following example:  

    override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.login_fragment, container, false)
    }

To reference a function in the parent class, use the`super`keyword, as shown in the following example:  

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
    }

### Nullability and initialization

In the previous examples, some of the parameters in the overridden methods have types suffixed with a question mark`?`. This indicates that the arguments passed for these parameters can be null. Be sure to[handle their nullability safely](https://kotlinlang.org/docs/reference/null-safety.html).

In Kotlin, you must initialize an object's properties when declaring the object. This implies that when you obtain an instance of a class, you can immediately reference any of its accessible properties. The`View`objects in a`Fragment`, however, aren't ready to be inflated until calling`Fragment#onCreateView`, so you need a way to defer property initialization for a`View`.

The`lateinit`lets you defer property initialization. When using`lateinit`, you should initialize your property as soon as possible.

The following example demonstrates using`lateinit`to assign`View`objects in`onViewCreated`:  

    class LoginFragment : Fragment() {

        private lateinit var usernameEditText: EditText
        private lateinit var passwordEditText: EditText
        private lateinit var loginButton: Button
        private lateinit var statusTextView: TextView

        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)

            usernameEditText = view.findViewById(R.id.username_edit_text)
            passwordEditText = view.findViewById(R.id.password_edit_text)
            loginButton = view.findViewById(R.id.login_button)
            statusTextView = view.findViewById(R.id.status_text_view)
        }

        ...
    }

| **Note:** If you access a property before it is initialized, Kotlin throws an`UninitializedPropertyAccessException`.

### SAM conversion

You can listen for click events in Android by implementing the`OnClickListener`interface.`Button`objects contain a`setOnClickListener()`function that takes in an implementation of`OnClickListener`.

`OnClickListener`has a single abstract method,`onClick()`, that you must implement. Because`setOnClickListener()`always takes an`OnClickListener`as an argument, and because`OnClickListener`always has the same single abstract method, this implementation can be represented using an anonymous function in Kotlin. This process is known as[Single Abstract Method conversion](https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions), or*SAM conversion*.

SAM conversion can make your code considerably cleaner. The following example shows how to use SAM conversion to implement an`OnClickListener`for a`Button`:  

    loginButton.setOnClickListener {
        val authSuccessful: Boolean = viewModel.authenticate(
                usernameEditText.text.toString(),
                passwordEditText.text.toString()
        )
        if (authSuccessful) {
            // Navigate to next screen
        } else {
            statusTextView.text = requireContext().getString(R.string.auth_failed)
        }
    }

The code within the anonymous function passed to`setOnClickListener()`executes when a user clicks`loginButton`.

### Companion objects

[Companion objects](https://kotlinlang.org/docs/tutorials/kotlin-for-py/objects-and-companion-objects.html#companion-objects)provide a mechanism for defining variables or functions that are linked conceptually to a type but are not tied to a particular object. Companion objects are similar to using Java's`static`keyword for variables and methods.

In the following example,`TAG`is a`String`constant. You don't need a unique instance of the`String`for each instance of`LoginFragment`, so you should define it in a companion object:  

    class LoginFragment : Fragment() {

        ...

        companion object {
            private const val TAG = "LoginFragment"
        }
    }

You could define`TAG`at the top level of the file, but the file might also have a large number of variables, functions, and classes that are also defined at the top level. Companion objects help to connect variables, functions, and the class definition without referring to any particular instance of that class.

### Property delegation

When initializing properties, you might repeat some of Android's more common patterns, such as accessing a`ViewModel`within a`Fragment`. To avoid excess duplicate code, you can use Kotlin's*property delegation*syntax.  

    private val viewModel: LoginViewModel by viewModels()

Property delegation provides a common implementation that you can reuse throughout your app. Android KTX provides some property delegates for you.`viewModels`, for example, retrieves a`ViewModel`that is scoped to the current`Fragment`.

Property delegation uses reflection, which adds some performance overhead. The tradeoff is a concise syntax that saves development time.

## Nullability

Kotlin provides strict nullability rules that maintain type-safety throughout your app. In Kotlin, references to objects cannot contain null values by default. To assign a null value to a variable, you must declare a*nullable* variable type by adding`?`to the end of the base type.

As an example, the following expression is illegal in Kotlin.`name`is of type`String`and isn't nullable:  

    val name: String = null

To allow a null value, you must use a nullable`String`type,`String?`, as shown in the following example:  

    val name: String? = null

### Interoperability

Kotlin's strict rules make your code safer and more concise. These rules lower the chances of having a`NullPointerException`that would cause your app to crash. Moreover, they reduce the number of null checks you need to make in your code.

Often, you must also call into non-Kotlin code when writing an Android app, as most Android APIs are written in the Java programming language.

Nullability is a key area where Java and Kotlin differ in behavior. Java is less strict with nullability syntax.

As an example, the`Account`class has a few properties, including a`String`property called`name`. Java does not have Kotlin's rules around nullability, instead relying on optional*nullability annotations*to explicitly declare whether you can assign a null value.

Because the Android framework is written primarily in Java, you might run into this scenario when calling into APIs without nullability annotations.

#### Platform types

If you use Kotlin to reference a unannotated`name`member that is defined in a Java`Account`class, the compiler doesn't know whether the`String`maps to a`String`or a`String?`in Kotlin. This ambiguity is represented via a*platform type* ,`String!`.

`String!`has no special meaning to the Kotlin compiler.`String!`can represent either a`String`or a`String?`, and the compiler lets you assign a value of either type. Note that you risk throwing a`NullPointerException`if you represent the type as a`String`and assign a null value.

To address this issue, you should use nullability annotations whenever you write code in Java. These annotations help both Java and Kotlin developers.

For example, here's the`Account`class as it's defined in Java:  

    public class Account implements Parcelable {
        public final String name;
        public final String type;
        private final @Nullable String accessId;

        ...
    }

One of the member variables,`accessId`, is annotated with`@Nullable`, indicating that it can hold a null value. Kotlin would then treat`accessId`as a`String?`.

To indicate that a variable can never be null, use the`@NonNull`annotation:  

    public class Account implements Parcelable {
        public final @NonNull String name;
        ...
    }

In this scenario,`name`is considered a non-nullable`String`in Kotlin.

Nullability annotations are included in all new Android APIs and many existing Android APIs. Many Java libraries have added nullability annotations to better support both Kotlin and Java developers.

#### Handling nullability

If you are unsure about a Java type, you should consider it to be nullable. As an example, the`name`member of the`Account`class is not annotated, so you should assume it to be a nullable`String?`.

If you want to trim`name`so that its value does not include leading or trailing whitespace, you can use Kotlin's`trim`function. You can safely trim a`String?`in a few different ways. One of these ways is to use the*not-null assertion operator* ,`!!`, as shown in the following example:  

    val account = Account("name", "type")
    val accountName = account.name!!.trim()

The`!!`operator treats everything on its left-hand side as non-null, so in this case, you are treating`name`as a non-null`String`. If the result of the expression to its left is null, then your app throws a`NullPointerException`. This operator is quick and easy, but it should be used sparingly, as it can reintroduce instances of`NullPointerException`into your code.

A safer choice is to use the*safe-call operator* ,`?.`, as shown in the following example:  

    val account = Account("name", "type")
    val accountName = account.name?.trim()

Using the safe-call operator, if`name`is non-null, then the result of`name?.trim()`is a name value without leading or trailing whitespace. If`name`is null, then the result of`name?.trim()`is`null`. This means that your app can never throw a`NullPointerException`when executing this statement.

While the safe-call operator saves you from a potential`NullPointerException`, it does pass a null value to the next statement. You can instead handle null cases immediately by using an*Elvis operator* (`?:`), as shown in the following example:  

    val account = Account("name", "type")
    val accountName = account.name?.trim() ?: "Default name"

If the result of the expression on the left-hand side of the Elvis operator is null, then the value on the right-hand side is assigned to`accountName`. This technique is useful for providing a default value that would otherwise be null.

You can also use the Elvis operator to return from a function early, as shown in the following example:  

    fun validateAccount(account: Account?) {
        val accountName = account?.name?.trim() ?: "Default name"

        // account cannot be null beyond this point
        account ?: return

        ...
    }

#### Android API changes

Android APIs are becoming increasingly Kotlin-friendly. Many of Android's most-common APIs, including`AppCompatActivity`and`Fragment`, contain nullability annotations, and certain calls like`Fragment#getContext`have more Kotlin-friendly alternatives.

For example, accessing the`Context`of a`Fragment`is almost always non-null, since most of the calls that you make in a`Fragment`occur while the`Fragment`is attached to an`Activity`(a subclass of`Context`). That said,`Fragment#getContext`does not always return a non-null value, as there are scenarios where a`Fragment`is not attached to an`Activity`. Thus, the return type of`Fragment#getContext`is nullable.

Since the`Context`returned from`Fragment#getContext`is nullable (and is annotated as @Nullable), you must treat it as a`Context?`in your Kotlin code. This means applying one of the previously-mentioned operators to address nullability before accessing its properties and functions. For some of these scenarios, Android contains alternative APIs that provide this convenience.`Fragment#requireContext`, for example, returns a non-null`Context`and throws an`IllegalStateException`if called when a`Context`would be null. This way, you can treat the resulting`Context`as non-null without the need for safe-call operators or workarounds.

### Property initialization

Properties in Kotlin are not initialized by default. They must be initialized when their enclosing class is initialized.

You can initialize properties in a few different ways. The following example shows how to initialize an`index`variable by assigning a value to it in the class declaration:  

    class LoginFragment : Fragment() {
        val index: Int = 12
    }

This initialization can also be defined in an initializer block:  

    class LoginFragment : Fragment() {
        val index: Int

        init {
            index = 12
        }
    }

In the examples above,`index`is initialized when a`LoginFragment`is constructed.

However, you might have some properties that can't be initialized during object construction. For example, you might want to reference a`View`from within a`Fragment`, which means that the layout must be inflated first. Inflation does not occur when a`Fragment`is constructed. Instead, it's inflated when calling`Fragment#onCreateView`.

One way to address this scenario is to declare the view as nullable and initialize it as soon as possible, as shown in the following example:  

    class LoginFragment : Fragment() {
        private var statusTextView: TextView? = null

        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
                super.onViewCreated(view, savedInstanceState)

                statusTextView = view.findViewById(R.id.status_text_view)
                statusTextView?.setText(R.string.auth_failed)
        }
    }

While this works as expected, you must now manage the nullability of the`View`whenever you reference it. A better solution is to use`lateinit`for`View`initialization, as shown in the following example:  

    class LoginFragment : Fragment() {
        private lateinit var statusTextView: TextView

        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
                super.onViewCreated(view, savedInstanceState)

                statusTextView = view.findViewById(R.id.status_text_view)
                statusTextView.setText(R.string.auth_failed)
        }
    }

The`lateinit`keyword allows you to avoid initializing a property when an object is constructed. If your property is referenced before being initialized, Kotlin throws an`UninitializedPropertyAccessException`, so be sure to initialize your property as soon as possible.
| **Note:** View binding solutions like[Data Binding](https://developer.android.com/topic/libraries/data-binding)that remove manual calls to`findViewById`can help reduce the number of null-safety issues you need to consider.