Как устроен экран приложения: Activity и View на Java
Activity — это экран (контроллер UI) и контейнер для иерархии View; View/ViewGroup — видимые элементы и макеты, которые Activity отображает и с которыми взаимодействует пользователь.
Что такое Activity и её жизненный цикл
Activity представляет один экран приложения и управляет состояниями интерфейса: создание, видимость, пауза и уничтожение. Ключевые методы жизненного цикла:
- onCreate(Bundle) — инициализация, установка layout через setContentView().
- onStart(), onResume() — Activity видима и готова к взаимодействию.
- onPause(), onStop() — нужно сохранять состояние и освобождать ресурсы.
- onDestroy() — финальная очистка.
Пример базовой Activity на Java:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); // подключаем XML-макет
Button button = findViewById(R.id.myButton);
button.setOnClickListener(v ->
Toast.makeText(this, "Кнопка нажата!", Toast.LENGTH_SHORT).show()
);
}
@Override
protected void onDestroy() {
super.onDestroy();
// очистка слушателей при необходимости
}
}
Советы:
- Сохраняйте состояние (onSaveInstanceState) при смене конфигурации.
- Переносите тяжёлую работу в фон (Executor, WorkManager).
View, ViewGroup и макеты (XML и программно)
View — базовый элемент: TextView, Button, ImageView. ViewGroup — контейнер для других View. Популярные макеты:
- ConstraintLayout — гибкий, уменьшает вложенность.
- LinearLayout — упорядочивает по оси, удобен для простых форм.
- FrameLayout — накладывает слои (контейнер для фрагментов). Используйте ViewBinding для типобезопасного доступа к элементам вместо ручного findViewById.
Пример XML с ConstraintLayout:
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/title"/>
</androidx.constraintlayout.widget.ConstraintLayout>
События, RecyclerView и фрагменты
Обработка кликов и жестов через OnClickListener, OnTouchListener или GestureDetector. Для длинных списков используйте RecyclerView с Adapter и ViewHolder:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private final List<String> items;
public static class MyViewHolder extends RecyclerView.ViewHolder {
TextView textView;
MyViewHolder(View v) { super(v); textView = v.findViewById(R.id.text); }
}
@Override public void onBindViewHolder(MyViewHolder holder, int pos) {
holder.textView.setText(items.get(pos));
holder.itemView.setOnClickListener(v -> handleClick(pos));
}
// остальные обязательные методы...
}
Фрагменты дают модульность внутри Activity, управляются FragmentManager и позволяют переиспользовать UI (телефон/планшет).
Используйте ViewBinding для безопасности типов и избегайте многократных вызовов findViewById.
Не выполняйте тяжёлые операции в UI-потоке — приложение будет "замерзать".
Частые ошибки
- Привязки в onCreate без проверки null после смены конфигурации — при пересоздании Activity элементы могут быть недоступны.
- Утечки: удержание ссылок на Context или Views в статических полях, не снятые слушатели.
- Сложные вложенные макеты — снижает производительность; заменяйте на ConstraintLayout.
- Блокировка главного потока при загрузке изображений или запросах сети — используйте Glide, Coil, Coroutines/Executor.
FAQ
- Нужно ли всегда использовать Fragment? Нет — фрагменты полезны для переиспользования UI и адаптивности, но простые экраны можно реализовать напрямую в Activity.
- Когда переходить на Jetpack Compose? Compose упрощает декларативный UI; переход имеет смысл при новых экранах и поддержке команды, но существующий код на View/ViewGroup остаётся рабочим.
- Как избежать утечек памяти с слушателями? Снимайте слушатели в onDestroy/onStop и не храните Activity в статических полях.
Начните с простого проекта: создайте Activity, добавьте несколько View в ConstraintLayout, подключите RecyclerView — и постепенно заменяйте устаревшие подходы на ViewBinding и архитектурные паттерны (MVVM).