DEV Community

Cover image for Android Lifecycle vs. React Native
Emerson Vieira
Emerson Vieira

Posted on

Android Lifecycle vs. React Native

Recentemente, acompanhei uma discussão em uma issue do Expo, mais especificamente sobre o expo-video, o modo fullscreen e o método exitFullscreen (implementação).

Problemática: você tenta executar um comando via JS enquanto o player está em fullscreen (por exemplo, fechar o player automaticamente ao final do vídeo) e... nada acontece. O diagnóstico imediato costuma ser: "O Android pausa o JS quando a Activity principal sai do topo, por isso o exitFullScreen não funciona."

Spoiler: Tem muita confusão entre Activity e Processo nessa história.

O equívoco do onPause e onStop

No Android, quando você entra em modo Fullscreen, geralmente uma nova Activity é criada para o player. A Activity principal (onde o JS nasceu) entra em onPause ou onStop.

Muita gente acha que onPause na Activity = Pausa no motor JavaScript.

A real é que o Android não pausa o motor JS (Hermes/JSC) só porque a Activity pausou. O que acontece é uma questão de prioridade de recursos:

  • Se a Activity principal não está visível, o Android "desprioriza" timers (setTimeout, setInterval).
  • O motor JS continua lá, mas o agendamento de tarefas fica na geladeira pra economizar bateria.

Processo vs. Activity

Se o app está mostrando um vídeo em Fullscreen, o processo do app ainda tem prioridade de Primeiro Plano (Foreground Priority).

O sistema operacional sabe que o app está ativo e visível. O motor JS está pronto para trabalhar, ele só não vai "se esforçar" por conta própria (timers).

Como "acordar" o JS?

Se você precisa que o JS execute algo (como fechar o player) enquanto outra Activity está por cima, a solução é parar de confiar em tempo e passar a confiar em Sinais do Sistema.

Eventos disparados pelo lado Nativo (como um callback de "vídeo terminou") conseguem furar a fila da "despriorização" do JS. O sinal viaja do Nativo -> Bridge/JSI -> JS, e o motor processa isso na hora, mesmo com a Activity principal em onPause.

Moral da história: O JS não está morto, ele só está esperando um motivo real (um evento nativo) para agir.

Top comments (0)