← Назад к вопросам

В чем разница между Activity Context и Application Context?

1.0 Junior🔥 161 комментариев
#Android компоненты

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

В чем разница между Activity Context и Application Context

Основное отличие

Activity Context привязан к конкретной Activity, существует столько же, сколько существует Activity. Application Context один на все приложение и живет столько же, сколько живет приложение.

// Activity Context
val activityContext: Context = this  // В Activity

// Application Context
val appContext: Context = getApplicationContext()  // или this в Application
val appContext2 = this@Activity.applicationContext

1. Жизненный цикл

Activity Context:

  • Создается при создании Activity
  • Уничтожается при уничтожении Activity
  • Привязан к UI
class MainActivity : AppCompatActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val context: Context = this  // Activity Context
    // При finish() этот контекст будет уничтожен
  }
}

Application Context:

  • Создается при запуске приложения
  • Живет до завершения процесса
  • Единственный на все время жизни app
class MyApp : Application() {
  override fun onCreate() {
    super.onCreate()
    val context: Context = this  // Application Context
    // Живет столько же, сколько живет приложение
  }
}

2. Использование в разных ситуациях

Когда использовать Activity Context

UI операции, привязанные к Activity:

class MainActivity : AppCompatActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    
    // Dialog привязан к Activity
    AlertDialog.Builder(this)  // Activity Context!
      .setTitle("Подтверждение")
      .setMessage("Вы уверены?")
      .show()
  }
}

Toast, View, LayoutInflater:

// Toast привязан к Activity и будет скрыт при её уничтожении
Toast.makeText(this, "Сообщение", Toast.LENGTH_SHORT).show()

// LayoutInflater связан с Activity
val view = LayoutInflater.from(this).inflate(R.layout.my_layout, null)

Animations, transitions:

val animator = ObjectAnimator.ofInt(this, "backgroundColor", Color.RED)
// Привязан к Activity

Когда использовать Application Context

Синглтоны, которые живут долго:

class DatabaseManager private constructor(context: Context) {
  private val appContext = context.applicationContext  // Берем Application Context!
  
  companion object {
    @Volatile
    private var instance: DatabaseManager? = null
    
    fun getInstance(context: Context) =
      instance ?: synchronized(this) {
        instance ?: DatabaseManager(context)
      }
  }
  
  // Database инициализируется один раз и живет до конца app
  private val database = Room.databaseBuilder(
    appContext,  // НЕ Activity Context!
    AppDatabase::class.java,
    "database.db"
  ).build()
}

Шаредпрефернцесы:

class PreferenceManager(context: Context) {
  private val appContext = context.applicationContext
  private val prefs = appContext.getSharedPreferences(
    "my_prefs",
    Context.MODE_PRIVATE
  )
  
  fun saveUser(name: String) {
    prefs.edit().putString("user_name", name).apply()
  }
}

Event Bus, Broadcast Receivers:

class EventBus(context: Context) {
  private val appContext = context.applicationContext
  
  fun registerReceiver(receiver: BroadcastReceiver, filter: IntentFilter) {
    appContext.registerReceiver(receiver, filter)  // Application Context!
  }
}

Network requests, API client:

class ApiClient(context: Context) {
  private val appContext = context.applicationContext
  
  private val httpClient = OkHttpClient()
  
  suspend fun getUsers(): List<User> {
    // HTTP запрос не привязан к Activity
    return httpClient.newCall(request).execute()
  }
}

3. Проблемы с неправильным использованием

❌ НЕПРАВИЛЬНО: Activity Context в Singleton

class BadRepository(context: Context) {
  // УТЕЧКА ПАМЯТИ!
  // Activity Context живет дольше Activity и держит её в памяти
  private val context = context  // Activity Context
  
  fun getData() {
    // Activity давно уничтожена, но её Context все еще в памяти
  }
}

Почему: Activity Context держит ссылку на всю Activity, включая все View'ы. Если Context живет в Singleton, то Activity никогда не будет garbage collected.

✅ ПРАВИЛЬНО: Application Context в Singleton

class GoodRepository(context: Context) {
  // ОК, Application Context живет столько же, сколько app
  private val appContext = context.applicationContext
  
  fun getData() {
    // Нет утечек памяти
  }
}

4. Сравнительная таблица

ХарактеристикаActivity ContextApplication Context
Жизненный циклРавен ActivityРавен приложению
Использование для UI✅ Да❌ Нет (нет доступа к Activity)
AlertDialog✅ Работает❌ Ошибка
Toast✅ Работает⚠️ Работает, но странно
Dialogs✅ Работает❌ Ошибка
Database⚠️ Работает, но утечка✅ Идеально
SharedPreferences⚠️ Работает, но утечка✅ Идеально
Service запуск⚠️ Работает, но утечка✅ Идеально
BroadcastReceiver⚠️ Работает, но утечка✅ Идеально

5. Практический пример: правильная архитектура

// Application класс - создает глобальные сервисы
@HiltAndroidApp
class MyApp : Application() {
  override fun onCreate() {
    super.onCreate()
    // Инициализируем Hilt, логирование и т.д.
  }
}

// Module для инъекции зависимостей
@Module
@InstallIn(SingletonComponent::class)
object RepositoryModule {
  @Provides
  @Singleton
  fun provideRepository(
    @ApplicationContext context: Context  // Application Context!
  ): UserRepository {
    return UserRepository(context)
  }
}

// Repository использует Application Context
class UserRepository(context: Context) {
  private val appContext = context.applicationContext
  private val database = Room.databaseBuilder(
    appContext,
    AppDatabase::class.java,
    "database.db"
  ).build()
}

// Activity использует Repository и свой Context для UI
class MainActivity : AppCompatActivity() {
  @Inject
  lateinit var repository: UserRepository
  
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    
    // Для UI используем Activity Context (this)
    AlertDialog.Builder(this)  // Activity Context!
      .setTitle("Загрузка")
      .show()
    
    // Для долгоживущих операций используем Repository
    lifecycleScope.launch {
      val users = repository.getUsers()  // Использует Application Context
    }
  }
}

Итог

Activity Context:

  • Для UI операций (Dialog, Toast, LayoutInflater)
  • Не используй в Singleton'ах и сервисах
  • Убивается вместе с Activity

Application Context:

  • Для сервисов, Database, SharedPreferences
  • Используй в Singleton'ах и долгоживущих объектах
  • Живет столько же, сколько приложение

Золотое правило: если объект будет жить дольше Activity — используй Application Context, иначе получишь утечку памяти!

В чем разница между Activity Context и Application Context? | PrepBro