@@ -39,28 +39,18 @@ import java.lang.ref.WeakReference
3939 * One service for all players.
4040 */
4141class PlayerService : MediaBrowserServiceCompat () {
42- private val player: Player by lazy {
43- Player (this ).apply {
44- /*
45- Create the player notification and start immediately the service in foreground,
46- otherwise if nothing is played or initializing the player and its components (especially
47- loading stream metadata) takes a lot of time, the app would crash on Android 8+ as the
48- service would never be put in the foreground while we said to the system we would do so
49- */
50- UIs ()[NotificationPlayerUi ::class .java].ifPresent {
51- it.createNotificationAndStartForeground()
52- }
53- }
54- }
42+ private var player: Player ? = null
5543
5644 private val mBinder: IBinder = LocalBinder (this )
57- private val compositeDisposableLoadChildren = CompositeDisposable ()
58- private var mediaBrowserConnector: MediaBrowserConnector ? = null
45+ private val disposables = CompositeDisposable ()
46+ private var _mediaBrowserConnector : MediaBrowserConnector ? = null
47+ private val mediaBrowserConnector: MediaBrowserConnector
5948 get() {
60- if (field == null ) {
61- field = MediaBrowserConnector (this )
49+ return _mediaBrowserConnector ? : run {
50+ val newMediaBrowserConnector = MediaBrowserConnector (this )
51+ _mediaBrowserConnector = newMediaBrowserConnector
52+ newMediaBrowserConnector
6253 }
63- return field
6454 }
6555
6656 val sessionConnector: MediaSessionConnector ?
@@ -78,13 +68,14 @@ class PlayerService : MediaBrowserServiceCompat() {
7868 Localization .assureCorrectAppLanguage(this )
7969 ThemeHelper .setTheme(this )
8070
71+ player = Player (this )
8172 /*
8273 Create the player notification and start immediately the service in foreground,
8374 otherwise if nothing is played or initializing the player and its components (especially
8475 loading stream metadata) takes a lot of time, the app would crash on Android 8+ as the
8576 service would never be put in the foreground while we said to the system we would do so
8677 */
87- player.UIs ()[NotificationPlayerUi ::class .java].ifPresent {
78+ player!! .UIs ()[NotificationPlayerUi ::class .java].ifPresent {
8879 it.createNotificationAndStartForeground()
8980 }
9081 }
@@ -112,11 +103,11 @@ class PlayerService : MediaBrowserServiceCompat() {
112103 If the service is already started in foreground, requesting it to be started shouldn't
113104 do anything
114105 */
115- player.UIs ()[ NotificationPlayerUi ::class .java] .ifPresent {
106+ player? .UIs ()?.get( NotificationPlayerUi ::class .java)? .ifPresent {
116107 it.createNotificationAndStartForeground()
117108 }
118109
119- if (Intent .ACTION_MEDIA_BUTTON == intent.action && (player.playQueue == null )) {
110+ if (Intent .ACTION_MEDIA_BUTTON == intent.action && (player? .playQueue == null )) {
120111 /*
121112 No need to process media button's actions if the player is not working, otherwise
122113 the player service would strangely start with nothing to play
@@ -127,8 +118,8 @@ class PlayerService : MediaBrowserServiceCompat() {
127118 return START_NOT_STICKY
128119 }
129120
130- player.handleIntent(intent)
131- player.UIs ()[ MediaSessionPlayerUi ::class .java] .ifPresent {
121+ player? .handleIntent(intent)
122+ player? .UIs ()?.get( MediaSessionPlayerUi ::class .java)? .ifPresent {
132123 it.handleMediaButtonIntent(intent)
133124 }
134125
@@ -140,17 +131,17 @@ class PlayerService : MediaBrowserServiceCompat() {
140131 Log .d(TAG , " stopForImmediateReusing() called" )
141132 }
142133
143- if (! player.exoPlayerIsNull()) {
134+ if (player != null && ! player!! .exoPlayerIsNull()) {
144135 // Releases wifi & cpu, disables keepScreenOn, etc.
145136 // We can't just pause the player here because it will make transition
146137 // from one stream to a new stream not smooth
147- player.smoothStopForImmediateReusing()
138+ player? .smoothStopForImmediateReusing()
148139 }
149140 }
150141
151142 override fun onTaskRemoved (rootIntent : Intent ) {
152143 super .onTaskRemoved(rootIntent)
153- if (! player.videoPlayerSelected()) {
144+ if (player != null && ! player!! .videoPlayerSelected()) {
154145 return
155146 }
156147 onDestroy()
@@ -166,14 +157,15 @@ class PlayerService : MediaBrowserServiceCompat() {
166157
167158 cleanup()
168159
169- mediaBrowserConnector? .release()
170- mediaBrowserConnector = null
160+ mediaBrowserConnector.release()
161+ _mediaBrowserConnector = null
171162
172- compositeDisposableLoadChildren .clear()
163+ disposables .clear()
173164 }
174165
175166 private fun cleanup () {
176- player.destroy()
167+ player?.destroy()
168+ player = null
177169 }
178170
179171 fun stopService () {
@@ -187,7 +179,7 @@ class PlayerService : MediaBrowserServiceCompat() {
187179
188180 override fun onBind (intent : Intent ): IBinder = mBinder
189181
190- // MediaBrowserServiceCompat methods
182+ // MediaBrowserServiceCompat methods (they defer function calls to mediaBrowserConnector)
191183 override fun onGetRoot (
192184 clientPackageName : String ,
193185 clientUid : Int ,
@@ -204,7 +196,7 @@ class PlayerService : MediaBrowserServiceCompat() {
204196 it.onLoadChildren(parentId).subscribe { mediaItems ->
205197 result.sendResult(mediaItems)
206198 }
207- compositeDisposableLoadChildren .add(disposable)
199+ disposables .add(disposable)
208200 }
209201 }
210202
0 commit comments