Player is accessed on the wrong thread.
- Dominant language
- Java
- Stars
- 21.9k
- Forks
- 6k
- PR merge metrics
- No merged PRs in 30d
Description
### ExoPlayer Version
2.17.1
### Devices that reproduce the issue
Vivo V2027 Android 12 (SDK 31)
Vivo V2130 Android 12 (SDK 31)
Vivo V2132 Android 12 (SDK 31)
Vivo X80 Android 12 (SDK 31)
Vivo V2146 Android 11 (SDK 30)
### Devices that do not reproduce the issue
POCO X3 Android 12 (SDK 31)
Samsung A32 Android 11 (SDK 30)
Infinix Note 7 Android 10 (SDK 29)
Sony Xperia ZX3 Android 10 (SDK 29)
### Reproducible in the demo app?
No
### Reproduction steps
none
### Expected result
don't crash
### Actual result
```
exception.class.missing._Unknown_: java.lang.IllegalStateException Player is accessed on the wrong thread.
at android.app.ActivityThread.handleStopService (ActivityThread.java:5021)
at android.app.ActivityThread.access$2400 (ActivityThread.java:284)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2327)
at android.os.Handler.dispatchMessage (Handler.java:106)
at android.os.Looper.loopOnce (Looper.java:233)
at android.os.Looper.loop (Looper.java:334)
at android.app.ActivityThread.main (ActivityThread.java:8399)
at java.lang.reflect.Method.invoke (Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:582)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1068)
Caused by: java.lang.IllegalStateException:
at com.google.android.exoplayer2.ExoPlayerImpl.verifyApplicationThread (ExoPlayerImpl.java)
at com.google.android.exoplayer2.ExoPlayerImpl.getCurrentTimeline (ExoPlayerImpl.java)
at com.google.android.exoplayer2.analytics.DefaultAnalyticsCollector.K (DefaultAnalyticsCollector.java:25)
at com.google.android.exoplayer2.analytics.DefaultAnalyticsCollector.generateEventTime (DefaultAnalyticsCollector.java)
at com.google.android.exoplayer2.analytics.DefaultAnalyticsCollector.generateReadingMediaPeriodEventTime (DefaultAnalyticsCollector.java)
at com.google.android.exoplayer2.analytics.DefaultAnalyticsCollector.onSurfaceSizeChanged (DefaultAnalyticsCollector.java)
at com.google.android.exoplayer2.ExoPlayerImpl.lambda$maybeNotifySurfaceSizeChanged$28 (ExoPlayerImpl.java)
at com.google.android.exoplayer2.ExoPlayerImpl$$InternalSyntheticLambda$0$2d4737b778d7b8503f2f9305c33da9d50db855343d46ce9f1ebd9b998f070724$0.invoke (ExoPlayerImpl.java)
at com.google.android.exoplayer2.util.ListenerSet$ListenerHolder.invoke (ListenerSet.java)
at com.google.android.exoplayer2.util.ListenerSet.lambda$queueEvent$0 (ListenerSet.java)
at com.google.android.exoplayer2.util.ListenerSet$$InternalSyntheticLambda$1$4aa6d67c50ced20c53fd0cecd314136314e77eb5e787a34f9137864aa48c8e5a$0.run (ListenerSet.java)
at com.google.android.exoplayer2.util.ListenerSet.flushEvents (ListenerSet.java:66)
at com.google.android.exoplayer2.util.ListenerSet.sendEvent (ListenerSet.java)
at com.google.android.exoplayer2.ExoPlayerImpl.maybeNotifySurfaceSizeChanged (ExoPlayerImpl.java)
at com.google.android.exoplayer2.ExoPlayerImpl.access$1800 (ExoPlayerImpl.java)
at com.google.android.exoplayer2.ExoPlayerImpl$ComponentListener.surfaceDestroyed (ExoPlayerImpl.java)
at android.service.wallpaper.WallpaperService$Engine.reportSurfaceDestroyed (WallpaperService.java:1945)
at android.service.wallpaper.WallpaperService$Engine.detach (WallpaperService.java:1971)
at android.service.wallpaper.WallpaperService.onDestroy (WallpaperService.java:2400)
at android.app.ActivityThread.handleStopService (ActivityThread.java:5001)
at android.app.ActivityThread.access$2400 (ActivityThread.java:284)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2327)
at android.os.Handler.dispatchMessage (Handler.java:106)
at android.os.Looper.loopOnce (Looper.java:233)
at android.os.Looper.loop (Looper.java:334)
at android.app.ActivityThread.main (ActivityThread.java:8399)
at java.lang.reflect.Method.invoke (Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:582)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1068)
```
### Code
```
open class MovieLiveWallpaperService : WallpaperService() {
private var contexts: Activity? = null
enum class Mode {
FIT_CENTER,
FIT_START,
FIT_END,
FIT_XY,
CENTER_CROP
}
private val mode: Mode
get() = AppSharedPreferences
.getStringDefValue(this,"scale_type", Mode.CENTER_CROP.name).let(
Mode::valueOf)
fun setToWallPaper(activity: Activity) {
Utility.sendEvent("Live_Engine")
contexts = activity
try {
val intent = Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER)
intent.putExtra(
WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT, ComponentName(
activity,
MovieLiveWallpaperService::class.java
)
)
activity.startActivity(intent)
} catch (ignore: ActivityNotFoundException) {
}
}
override fun onCreateEngine(): Engine = GlEngine()
protected fun initExoMediaPlayer(): ExoPlayer {
val player = this.let { ExoPlayer.Builder(it).build() }
player.videoScalingMode = C.VIDEO_SCALING_MODE_SCALE_TO_FIT
player.playWhenReady = true
player.repeatMode = Player.REPEAT_MODE_ONE
player.volume = 0f
if (mode == Mode.CENTER_CROP) {
player.videoScalingMode = C.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING
} else {
player.videoScalingMode = C.VIDEO_SCALING_MODE_SCALE_TO_FIT
}
if (mode == Mode.FIT_CENTER) {
player.addListener(object : Player.Listener {
override fun onPlayerError(error: PlaybackException) {
super.onPlayerError(error)
contexts?.let {
Toast.makeText(
it,
"${error.message} Something Went Wrong!",
Toast.LENGTH_SHORT
).show()
}
}
})
}
return player
}
inner class GlEngine : WallpaperService.Engine() {
private var exoMediaPlayer = initExoMediaPlayer()
override fun onVisibilityChanged(visible: Boolean) {
exoMediaPlayer.playWhenReady = visible
if (visible) onResume()
else onPause()
}
@Synchronized
override fun onSurfaceCreated(holder: SurfaceHolder) {
kotlin.runCatching {
if (mode == Mode.FIT_CENTER) {
exoMediaPlayer.setVideoSurface(holder.surface)
} else {
exoMediaPlayer.setVideoSurfaceHolder(holder)
}
val videoUri = this@MovieLiveWallpaperService.let {
AppSharedPreferences.getString(
it,
"absolutePath"
)
}
val isLocalVideo =
AppSharedPreferences.getBool(this@MovieLiveWallpaperService, "isLocalVideo")
when {
isLocalVideo -> exoMediaPlayer.setMediaSource(
buildMediaSourceForLocal(
Uri.parse(
videoUri
)
)
)
!isLocalVideo -> exoMediaPlayer.setMediaSource(
buildMediaSource(
Uri.parse(
videoUri
)
)
)
}
exoMediaPlayer.prepare()
exoMediaPlayer.play()
}
}
private fun buildMediaSource(uri: Uri): MediaSource {
val userAgent = "exoplayer-liveWallpaper"
val media_item: MediaItem = MediaItem.fromUri(uri)
val cache_datasource_factory = CacheDataSource.Factory()
.setCache(EngineVideoCache.getInstance(this@MovieLiveWallpaperService))
.setUpstreamDataSourceFactory(
DefaultHttpDataSource.Factory()
.setUserAgent(userAgent)
)
return ProgressiveMediaSource.Factory(cache_datasource_factory)
.createMediaSource(media_item)
}
private fun buildMediaSourceForLocal(uri: Uri): MediaSource {
val media_item: MediaItem = MediaItem.fromUri(uri)
val dataSource = CacheDataSource.Factory()
.setCache(EngineVideoCache.getInstance(this@MovieLiveWallpaperService))
.setUpstreamDataSourceFactory(DefaultDataSource.Factory(this@MovieLiveWallpaperService))
return ProgressiveMediaSource.Factory(dataSource)
.createMediaSource(media_item)
}
override fun onSurfaceChanged(
holder: SurfaceHolder?,
format: Int,
width: Int,
height: Int
) {
}
@Synchronized
override fun onSurfaceDestroyed(holder: SurfaceHolder?) {
}
override fun onDestroy() {
kotlin.runCatching {
super.onDestroy()
exoMediaPlayer.stop()
exoMediaPlayer.release()
}
}
private fun onPause() {
kotlin.runCatching {
exoMediaPlayer.pause()
}
}
private fun onResume() {
kotlin.runCatching {
exoMediaPlayer.play()
}
}
}
}
```
### Bug Report
- [ ] You will email the zip file produced by `adb bugreport` to dev.exoplayer@gmail.com after filing this issue.
Contributor guide
Assessment
This issue has not been assessed yet.