Why onTapEvent method of OnGestureListenerAdapter is invoked on background thread?

Viewed 112

We are using premium SDK and OnTapEvent callback of OnGestureListenerAdapter interface is invoked on background thread. Is it intended behaviour or bug in SDK?

Tried to find answer in docs but there is no info about this behaviour.

val state = MutableLiveData<MapViewState>()

override fun onTapEvent(point: PointF): Boolean {
        viewModel.onMapClick()
        return false
    }

fun onMapClick() {
        state.setValue(state.copy(selected = None))
    }

Getting error when trying to set value to LiveData directly from onTapEvent.

    java.lang.IllegalStateException: Cannot invoke setValue on a background thread
        at androidx.lifecycle.LiveData.assertMainThread(LiveData.java:443)
        at androidx.lifecycle.LiveData.setValue(LiveData.java:286)
        at androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:33)
        at com.example.MapFragment.onTapEvent(MapFragment.kt:121)
        at com.nokia.maps.MapGestureHandlerBase.a(MapGestureHandlerBase.java:253)
        at com.nokia.maps.MapGestureHandlerBase.a(MapGestureHandlerBase.java:230)
        at com.nokia.maps.NmaaGestureHandler.handleTap(NmaaGestureHandler.java:230)
        at com.nokia.maps.NmaaGestureHandler.pollNative(Native Method)
        at com.nokia.maps.NmaaGestureHandler.a(NmaaGestureHandler.java:26)
        at com.nokia.maps.NmaaGestureHandler$a.d(NmaaGestureHandler.java:379)
        at com.nokia.maps.NmaaGestureHandler$a.c(NmaaGestureHandler.java:371)
        at com.nokia.maps.NmaaGestureHandler$a.a(NmaaGestureHandler.java:363)
        at com.nokia.maps.NmaaGestureHandler$a$1.a(NmaaGestureHandler.java:390)
        at com.nokia.maps.NmaaGestureHandler$b.run(NmaaGestureHandler.java:429)

Seems logic to have this callback invoked on main thread.

1 Answers

Quick answer is: to avoid ANR. SDK user can write heavy code and that will cause application not responding issue. There are two ways to solve the issue:

1) Post your actions to UI thread like below:

                    new Handler(Looper.getMainLooper()).post(new Runnable() {
                        @Override
                        public void run() {
                            // customer code
                        }
                    });

2) Use asynchronous listeners, which are called on UI thread. You have to register your gesture listener using "false" value as third param:

m_mapGesture.addOnGestureListener(gestureListener, 0, false);

Hope this helps!

Related