fix(android): 0.4.2 domyka crash expo-video przy zamykaniu apki

Latka z 0.4.1 kopiowala mape sesji przed zwolnieniem playerow, ale sama kopia
tez iteruje mape, a wpisy znikaja z innego watku. Na LinkedHashMap wywalalo sie
wiec dalej, juz w toList() (Sentry GOON-6W, Redmi Note 8 Pro, Android 11).
Mapa jest teraz ConcurrentHashMap, iteracja przezyje rownolegle usuniecie.

versionCode 16 zeby posiadacze 0.4.0/0.4.1 dostali monit: runtime zostaje 1.4,
wiec sam numer kanalu ich nie rozrozni.

Sprawdzone na emulatorze: dwie sesje mediow zywe, zamkniecie z listy ostatnich
zwalnia obie, pusty bufor crashy.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
goon-foss 2026-09-17 15:19:28 +02:00
parent 3c1d2c5907
commit 6b06cc96bf
6 changed files with 27 additions and 8 deletions

View file

@ -133,9 +133,9 @@ def version() -> dict[str, str | int | None]:
# expo-video przy zamykaniu z ostatnich (Sentry 147164135, zgłoszenie 2026-09-15).
# Podbijaj RAZEM z `version` przy każdym wydaniu APK.
return {
"version": "0.4.1",
"version": "0.4.2",
"runtime_version": "1.4",
"apk_build": 15,
"apk_build": 16,
"apk_url": apk_url,
}

View file

@ -104,8 +104,8 @@ android {
applicationId 'com.goon.mobile'
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 15
versionName "0.4.1"
versionCode 16
versionName "0.4.2"
}
signingConfigs {
debug {

View file

@ -2,7 +2,7 @@
"expo": {
"name": "goon",
"slug": "goon",
"version": "0.4.1",
"version": "0.4.2",
"orientation": "portrait",
"userInterfaceStyle": "automatic",
"newArchEnabled": false,

View file

@ -1,8 +1,16 @@
diff --git a/node_modules/expo-video/android/src/main/java/expo/modules/video/playbackService/ExpoVideoPlaybackService.kt b/node_modules/expo-video/android/src/main/java/expo/modules/video/playbackService/ExpoVideoPlaybackService.kt
index cd798cf..34923b2 100644
--- a/node_modules/expo-video/android/src/main/java/expo/modules/video/playbackService/ExpoVideoPlaybackService.kt
+++ b/node_modules/expo-video/android/src/main/java/expo/modules/video/playbackService/ExpoVideoPlaybackService.kt
@@ -136,10 +136,14 @@ class ExpoVideoPlaybackService : MediaSessionService() {
@@ -26,7 +26,7 @@ class PlaybackServiceBinder(val service: ExpoVideoPlaybackService) : Binder()
@OptIn(UnstableApi::class)
class ExpoVideoPlaybackService : MediaSessionService() {
- private val mediaSessions = mutableMapOf<ExoPlayer, MediaSession>()
+ private val mediaSessions = java.util.concurrent.ConcurrentHashMap<ExoPlayer, MediaSession>()
private val binder = PlaybackServiceBinder(this)
private val commandSeekForward = SessionCommand(SEEK_FORWARD_COMMAND, Bundle.EMPTY)
@@ -136,10 +136,17 @@ class ExpoVideoPlaybackService : MediaSessionService() {
private fun cleanup() {
hideAllNotifications()
@ -10,6 +18,9 @@ index cd798cf..34923b2 100644
+ // Kopia przed iteracja: session.release() wola z powrotem unregisterPlayer, ktory
+ // usuwa wpis z mediaSessions w trakcie forEach -> ConcurrentModificationException
+ // przy zamykaniu apki z listy ostatnich (Goon, Sentry 147164135, 2026-09-15).
+ // Mapa jest ConcurrentHashMap (patrz deklaracja), bo sama kopia tez iteruje mape,
+ // a wpisy znikaja z innego watku przy zwalnianiu playera: na LinkedHashMap `toList()`
+ // wywalalo sie wtedy tak samo (Goon 0.4.1, Sentry GOON-6W, 2026-09-17).
+ val sessions = mediaSessions.values.toList()
+ mediaSessions.clear()
+ sessions.forEach { session ->

View file

@ -35,6 +35,14 @@ export type ChangelogEntry = {
};
export const CHANGELOG: ChangelogEntry[] = [
{
id: '2026-09-17b',
date: 'September 2026',
items: [
'Version 0.4.2 fixes the crash when closing the app while a video was open. The previous attempt only covered part of it: the list of players could also change from another thread while it was being copied.',
'Android TV: the app now shows up on the TV home screen, runs full screen and can be driven with the remote on the existing screens. It is not a purpose-built TV interface yet: there is no focus highlight, and sites that ask you to tap a human check are painful with a remote.',
],
},
{
id: '2026-09-17a',
date: 'September 2026',

View file

@ -18,7 +18,7 @@ import * as Updates from 'expo-updates';
* też nie idzie do góry, więc consistency jest zachowana.
*/
export const APP_VERSION: string =
(Constants.expoConfig?.version as string | undefined) || '0.4.0';
(Constants.expoConfig?.version as string | undefined) || '0.4.2';
/**
* Runtime zapisany w APK (`EXPO_RUNTIME_VERSION` w AndroidManifest). JEDYNY numer, po