1

Trying to get lastLocation and once it's done call api. But somehow once location is obtained my api calls always running in mainThread, so i'm getting exception:

android.io.NetworkOnMainThreadException

Here is my location observer:

fun getLocation(): Single<Location> {
        return Single.create<Location> { subscriber ->
            fusedLocationClient.lastLocation.addOnSuccessListener {
                if (it != null) {
                    subscriber.onSuccess(it)
                } else {
                    subscriber.onError(Exception("No location"))
                }
            }
        }
    }

Code that does some transformations

val locationObserver = getLocation()
observables.add(locationObserver.flatMap { _ -> sendDataToServer(data)})

Observer

Single.zip(observables) { args1 -> args1 }.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe({
            Timber.i("Success")

        }, {
            Timber.i("Error %s", observables.size, it.localizedMessage)
            it.printStackTrace()
        })

I've set subscribeOn so it shouldn't be on mainThread, but looks like something missed.

Found that if i will use something like Single.just("One").flatMap{ ... } that will work fine and will be executed on non-main thread.

Is there something to do with getLocation function?

1 Answer 1

1

The order of subscribeOn, observeOn, subscribe, and transformations matters. Apparently, it's needed to do the transformations, in this case, the flatMap after specifying the observer thread with observeOn to make sure the code is executed in the right thread.

Sign up to request clarification or add additional context in comments.

4 Comments

After subscribe block it’s no longer observable, so you can’t do that. It’s applicable only before subscribe call
Oh my bad, what if you switch the order of subscribeOn and observeOn? I used to have a similar problem and changing these orders is what solved it.
Oh damn, you pointed me in right direction. Please modify your answer to use observeOn(Schedulers.io()) before .flatMap{}
Glad I did, I have edited the answer, make sure that's what you meant.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.