1. 程式人生 > >ExoPlayer踩坑:IndexOutOfBoundsException

ExoPlayer踩坑:IndexOutOfBoundsException

專案中語音播放用到Google開源的ExoPlayer,基本使用很簡單,但是線上還是出現了一些測試沒有發現的crash。其中一個就是IndexOutOfBoundsException。

com.google.android.exoplayer2.Timeline$1.getPeriod(Timeline.java:516)
2 com.google.android.exoplayer2.Timeline.getPeriod(Timeline.java:749)
3 com.google.android.exoplayer2.ExoPlayerImpl.playbackInfoPositionUsToWindowPositionMs(ExoPlayerImpl.java:689)
4 com.google.android.exoplayer2.ExoPlayerImpl.getCurrentPosition(ExoPlayerImpl.java:474)
5 com.google.android.exoplayer2.ExoPlayerImpl.getContentPosition(ExoPlayerImpl.java:529)
6 com.google.android.exoplayer2.analytics.AnalyticsCollector.generateEventTime(AnalyticsCollector.java:575)
7 com.google.android.exoplayer2.analytics.AnalyticsCollector.generateEventTime(AnalyticsCollector.java:602)
8 com.google.android.exoplayer2.analytics.AnalyticsCollector.generatePlayingMediaPeriodEventTime(AnalyticsCollector.java:612)
9 com.google.android.exoplayer2.analytics.AnalyticsCollector.onTimelineChanged(AnalyticsCollector.java:425)
10 com.google.android.exoplayer2.ExoPlayerImpl$PlaybackInfoUpdate.notifyListeners(ExoPlayerImpl.java:746)
11 com.google.android.exoplayer2.ExoPlayerImpl.updatePlaybackInfo(ExoPlayerImpl.java:681)
12 com.google.android.exoplayer2.ExoPlayerImpl.handlePlaybackInfo(ExoPlayerImpl.java:622)
13 com.google.android.exoplayer2.ExoPlayerImpl.handleEvent(ExoPlayerImpl.java:567)
14 com.google.android.exoplayer2.ExoPlayerImpl$1.handleMessage(ExoPlayerImpl.java:109)
15 android.os.Handler.dispatchMessage(Handler.java:102)
16 android.os.Looper.loop(Looper.java:135)
17 android.app.ActivityThread.main(ActivityThread.java:5318)

錯誤棧中沒有出現app的包名,一臉懵。於是只能google一下,還好發現了問題。在ExoPlayer文件的執行緒模型中,明確提到了播放器例項必須在一個執行緒中進行操作。

ExoPlayer instances must be accessed from a single application thread. For the vast majority of cases this should be the application’s main thread. Using the application’s main thread is also a requirement when using ExoPlayer’s UI components or the IMA extension. The thread on which an ExoPlayer instance must be accessed can be explicitly specified by passing a Looper

when creating the player. If no Looper is specified, then the Looper of the thread that the player is created on is used, or if that thread does not have a Looper, the Looper of the application’s main thread is used. In all cases the Looper of the thread from which the player must be accessed can be queried using Player.getApplicationLooper().

參考: