0

I have a TimerService that I'd like to bind to with a TimerFragment, so I can call the Service's methods and observe its LiveData in the fragment. The problem I'm running into is that when I start my fragment, it's telling me that the lateinit var timerService hasn't been initialized by the time I try to use it in onStart. I thought I was starting the service and binding to it by that time in the fragment lifecycle, so I'm not sure what's causing the issue.

My fragment code is as follows:

class TimerFragment : Fragment() {

    private lateinit var scaleUp: ObjectAnimator
    private lateinit var alphaDown: ObjectAnimator

    private lateinit var timerService: TimerService
    private var bound = false

    private val connection = object : ServiceConnection {
        override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
            val binder = service as TimerService.LocalBinder
            timerService = binder.getService()
            bound = true
        }

        override fun onServiceDisconnected(name: ComponentName?) {
            bound = false
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setHasOptionsMenu(true)

        requireActivity().startService(Intent(requireContext(), TimerService::class.java))
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_timer, container, false)
    }

    override fun onStart() {
        super.onStart()
        Intent(requireContext(), TimerService::class.java).also{ intent ->
            requireActivity().bindService(intent, connection, Context.BIND_AUTO_CREATE)
        }

        timerService.secondsElapsed.observe(viewLifecycleOwner, Observer {
            updateTimerUI(it)
        })

        timerService.timerState.observe(viewLifecycleOwner, Observer {
            updateButtons(it)
        })
    }

    override fun onStop() {
        super.onStop()
        requireActivity().unbindService(connection)
        bound = false
    }

    // other stuff
}

Cameron
  • 1,281
  • 1
  • 19
  • 40
  • 2
    because bindService is async, move `timerService.secondsElapsed.observe` and `timerService.timerState.observe` to `onServiceConnected` – IR42 Jul 18 '20 at 18:05
  • Yep, that fixed it, thanks. I didn't realize that call was async – Cameron Jul 18 '20 at 18:11

0 Answers0