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)