Доступ к MainActivity.this в Kotlin: правильное использование

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Чтобы обращаться к контексту текущей Activity в Kotlin, используете this@НазваниеВашейActivity.

kotlin
Скопировать код
class ВашаActivity : AppCompatActivity() {
    fun initListener() {
        button.setOnClickListener {
            // Получаем ссылку на текущую Activity с помощью знака @ 🥳
            startActivity(Intent(this@ВашаActivity, ДругаяActivity::class.java))
        }
    }
}

Выражение this@ВашаActivity явно указывает контекст Activity, что необходимо для корректности операций.

Кинга Идем в IT: пошаговый план для смены профессии

Понимание концепции "this"

Важность явного указания контекста во вложенных классах

В вложенных классах, например, OnClickListener, сущность this по умолчанию ведёт себя как ссылка на эти классы. Поэтому необходимо указать контекст Activity явно:

kotlin
Скопировать код
class МояActivity : AppCompatActivity() {
    init {
        myButton.setOnClickListener(object : View.OnClickListener {
            override fun onClick(v: View?) {
                // Указав точный контекст, мы избегаем путаницы 📬
                showSnackBar(this@МояActivity, "Кнопка была нажата!")
            }
        })
    }
}

Функция "this" в расширяющих функциях

В расширяющих функциях this обозначает объект, на который создано расширение. Если создавать расширение для Activity, this можно использовать напрямую:

kotlin
Скопировать код
fun Activity.showHelloToast() {
    // Иногда "this@Activity" можно опустить 😉
    Toast.makeText(this, "Привет", Toast.LENGTH_SHORT).show()
}

Применение "this" при создании конструкторов

При создании диалогов или в других случаях, где требуется контекст, используйте this@ВашаActivity:

kotlin
Скопировать код
class МояActivity : AppCompatActivity() {
    fun showDialog() {
        // В нужном контексте можно поставить нодобимую "сцену" 🎬
        AlertDialog.Builder(this@МояActivity)
            .setTitle("Внимание")
            .setMessage("'this' в конструкторе диалога")
            .show()
    }
}

Избегайте эти подводные камни

Работа с контекстами

В Kotlin контекст имеет важное значение. Неправильное использование контекстов может привести к утечкам памяти или другим проблемам. Внимательно выбирайте this, отводя его применение.

Обращение к внутренним классам

Внутренний класс без модификатора inner в Activity не имеет доступа к Activity. Для доступа используйте модификатор inner:

kotlin
Скопировать код
class МояActivity : AppCompatActivity() {
    inner class МойВнутреннийКласс {
        fun myFunction() {
            // Разрешение контекста с использованием "inner" 🔑
            val activity = this@МояActivity
            // Используем ссылку на Activity
        }
    }
}

Визуализация

Попробуем проиллюстрировать использование this@НазваниеActivity. На маскараде 🎭 если в Java мы бы сказали: "Эй, тот в маске!", то в Kotlin достаточно указать имя.

kotlin
Скопировать код
button.setOnClickListener {
    // Обращение на прямую к нужному объекту
    doSomething(this@Activity)
}

Синтаксис @НазваниеActivity позволяет нам однозначно и точно обрабатываться к Activity.

Рекомендации экспертов по написанию понятного и эффективного кода

Сокращайте с помощью typealias

Для повышения читаемости кода в случае длинных названий, используйте typealias:

kotlin
Скопировать код
typealias Act = МояОченьДлиннаяActivity

class МояОченьДлиннаяActivity : AppCompatActivity() {
    fun someMethod() {
        // Ваш код становится более понятным 😜
        someFunctionNeedingContext(this@Act)
    }
}

Передавайте контекст во внешние классы

При передаче контекста Activity во внешние классы, делайте это через явные аргументы методов, чтобы сохранять чистоту кода.

Используйте привязку к представлениям

View Binding в Kotlin это современная альтернатива устаревшим synthetics для безопасной работы с представлениями:

kotlin
Скопировать код
import com.example.databinding.ActivityMainBinding

class МояActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view)
        // Встретим безошибочное использование виджетов! 😄
        binding.textViewTitle.text = "Добро пожаловать!"
    }
}

Полезные материалы