Locus Map - forum

Development => Developers => Topic started by: TrulloF on April 13, 2026, 08:49:49

Title: Custom router over API
Post by: TrulloF on April 13, 2026, 08:49:49
[Bug] InvalidObjectException crash when tapping navigation tile with external routing providers - ACTION_COMPUTE_TRACK_PROVIDER service not yet bound

Hi Menion,

I'm developing a third-party routing addon with the help of Claude Code that registers as an ACTION_COMPUTE_TRACK_PROVIDER service. Routing and rerouting work correctly, but Locus crashes whenever the navigation tile is tapped during active navigation (or when the navigation menu is opened, e.g. from the point menu, without having gone through Navigation → Routing first).

Crash:

java.io.InvalidObjectException: Service does not return valid 'trackTypes'

Root cause:
The navigation tile/menu ViewModel enumerates all registered ACTION_COMPUTE_TRACK_PROVIDER services and calls getTrackTypes() on each one synchronously, before onServiceConnected() has fired for services that haven't been bound in the current session. Internally, the API proxy guards every call with an isConnected flag that is only set inside onServiceConnected(). If the service wasn't previously bound, isConnected is still false at call time → InvalidObjectException.

100% reproducible steps:

Install any app (e.g. BRouter) that exports a service with action="locus.api.android.ACTION_COMPUTE_TRACK_PROVIDER".
Start a navigation session without going through Navigation → Routing (so the service was never bound in this session).
Tap the navigation tile during active navigation.
Crash.
Suggested fix (Locus side):

Wrap the getTrackTypes() call in a try/catch and treat the service as temporarily unavailable rather than crashing:

try {
    int[] types = service.getTrackTypes();
    // use types
} catch (InvalidObjectException | RemoteException e) {
    Log.w(TAG, "Routing service not yet connected, skipping: " + e.getMessage());
}

Alternatively, collect track types asynchronously inside onServiceConnected() and update the UI once binding completes, rather than calling eagerly before the connection is established.

Thanks for looking into this!
Title: Re: Custom router over API
Post by: Menion on April 15, 2026, 14:47:19
Hi @TrulloF
Nice to see someone playing with the API! To be honest, this API functionality is not used by any addon, so it is, as you see, not well tested.

Anyway, in this case > issue found and should be fixed in the next (Friday probably) version.

Title: Re: Custom router over API
Post by: TrulloF on April 16, 2026, 08:34:19
Thanks for looking into it. BRouter, if installed as separate app is also affected by this bug. It crashes Locus, if you try to plan a route or try to navigate from the point menu. Because BRouter is now integrated into Locus Map, probably nobody noticed.

Quote from: Menion on April 15, 2026, 14:47:19Hi @TrulloF
Nice to see someone playing with the API! To be honest, this API functionality is not used by any addon, so it is, as you see, not well tested.

Anyway, in this case > issue found and should be fixed in the next (Friday probably) version.


Title: Re: Custom router over API
Post by: TrulloF on April 18, 2026, 19:21:10
Problem is fixed with the latest build. Great work. Now I can route with my TomTom-addon in Locus and use traffic information to avoid traffic jams. That was the only thing missing for me. Thanks to Claude Code... 😊
By the way, if you enabled Google location services in GPS & Sensor settings, but have only MicroG installed, GPS position will be found but the GPS icon stays yellow and position doesn't follow during routing, even though the signal is strong. Only disabling this option fixed it for me.
Title: Re: Custom router over API
Post by: Menion on April 21, 2026, 15:12:12
Hmm, nice!

And MicroG problem ... I can't test it. Probably some problem in the Google Services location implementation.
Title: Re: Custom router over API
Post by: TrulloF on April 26, 2026, 10:27:51
The problem with external routers crashing is only half gone. I have to open the settings of the addon, before trying any routing activities. If not the app crashes while initializing/enumerating the present routing services. I'll send a better description and a log, if I find the time. I can live with the current situation. It's just an additional step before I can start routing. So take your time.
Title: Re: Custom router over API
Post by: Menion on April 26, 2026, 21:59:02
Hmm are you willing to privately share your add-on so I may test it more precisely? There is probably an API key inside, so I will of course, delete the add-on once it is fixed. At least a log for now, thanks!
Title: Re: Custom router over API
Post by: TrulloF on May 01, 2026, 12:24:00
Sent you a PM. Thank you for looking into it.
Title: Re: Custom router over API
Post by: TrulloF on June 02, 2026, 22:47:37
Can we expect a fix for the third party routing addons soon? Even with the latest build I need to tap the settings button of the external navigation service once or else the app either restarts or crashes right away. Did I miss something with my implementation?
Title: Re: Custom router over API
Post by: Menion on June 03, 2026, 08:20:30
Hello TrulloF,
ah sorry, I've missed your PM and now the request is no longer valid. Once more please, thanks.
Title: Re: Custom router over API
Post by: TrulloF on June 03, 2026, 14:52:30
Thank you for your reply. I sent another invite. BR
Title: Re: Custom router over API
Post by: TrulloF on June 03, 2026, 17:32:12
Hi Menion,

I can confirm it is still reproducible on 4.34.1.2 (versionCode 1214). I think I now understand exactly why it happens and what the fix should be.

---
Crash (condensed logcat, 4.34.1.2):

FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity
  ComponentInfo{.../RoutePlannerActivity}:
  An exception happened in constructor of class xt.d1
Caused by: java.io.InvalidObjectException: Service does not return valid 'trackTypes'
    at vr.q.m(...)
    at gx.b.k(...)
    at xt.d1.<init>(163)
    at RoutePlannerActivity.K0(...)
    at RoutePlannerActivity.onCreate(...)

---
Root cause

Android's Context.bindService() is asynchronous - the binder is only available after onServiceConnected() fires. If RoutePlannerActivity opens before that callback has fired (i.e. in any fresh Locus session where the user hasn't visited routing settings yet), Locus asks the external service for its trackTypes while it is not yet connected.
Instead of treating "not yet connected" as a transient state and returning an empty list, Locus throws InvalidObjectException - which propagates uncaught out of the ViewModel constructor and crashes the Activity.

This is a race condition inherent to the Android binding lifecycle: there is no way for an external addon to guarantee it is pre-connected before the user opens the route planner.

---
Suggested fix

When an external ACTION_COMPUTE_TRACK_PROVIDER service is registered but its onServiceConnected() has not fired yet, getTrackTypes() should return an empty array rather than throw. An empty array is a valid transient state - the UI can show a spinner or refresh once the connection is established. Throwing an uncaught exception from a ViewModel constructor is never recoverable.

The error message "Service does not return valid 'trackTypes'" already exists as a user-facing toast for when something goes wrong during active use - that path is fine. The issue is specifically the throw propagating up into RoutePlannerActivity.onCreate() before the service has even had a chance to connect.

---
Workaround for users until fixed: in Locus Routing Settings, tap the configure icon next to the external router once per session. This triggers bindService() explicitly and the crash won't occur for the rest of the session.

Thank you!
Title: Re: Custom router over API
Post by: Menion on June 04, 2026, 14:54:59
Hello TrulloF,

thanks for the access to the project. This API was never used in production, so good time to make it work. The serious problem in how the app handles async access to service metadata should be fixed now.

Not ideal, but should work. Give a try to the next Beta version, tomorrow.
Title: Re: Custom router over API
Post by: TrulloF on June 04, 2026, 22:00:10
The Locus api works very well. I now fully replaced the standalone TomTom app with Locus and TomTom routing addon for car navigation. It's cheaper too, because the developer api key is free. Of course things like lane assist or 1:1 traffic sign texts aren't possible, but we can get pretty close. If the rerouting is correctly triggered by traffic jams ahead is yet to be tested, but normal navigation works as intended. Roundabouts were quite tricky, but now I got them working with correct exit numbers.
I'm extremely happy with the tools and customization options Locus provides. Near endless possibilities. Thanks for this great app!
Title: Re: Custom router over API
Post by: Menion on June 05, 2026, 07:47:57
Glad to read it :)

I noticed you have a settings screen with not just an API key, but a lot of other options. The app is missing an option to directly access these settings from the Route planner. Have to look at it.
Title: Re: Custom router over API
Post by: TrulloF on June 05, 2026, 09:12:09
For my use case it's not necessary to access the addon settings from within the route planner. I imagine the mapping of settings might be rather complex too. It's enough, when the app doesn't crash without going to the addon settings before using any navigation features. It's just a nuisance, but annoying nonetheless  ;)
Title: Re: Custom router over API
Post by: TrulloF on June 20, 2026, 21:46:45
Another bug report - RoutePlannerActivity ANR while navigating to a point during movement (external routing engine)

Environment
Locus Map 4.34.1.4 (versionCode 1214)
Android 12L (API 32), Sony Xperia XZ1 Compact (LineageOS, rooted)
Routing engine selected: an external ACTION_COMPUTE_TRACK_PROVIDER addon
Reproduced while driving (continuous GPS fixes), GPS valid throughout.

Summary
When an external routing engine is the selected router and the user starts navigation to a point (built-in "Navigate to") while the vehicle is moving, RoutePlannerActivity becomes unresponsive for ~30 s, then the route collapses to a degenerate state (start == destination) and navigation cannot start. Two on-device ANR traces were captured; both are ANRs in the route planner caused by the UI thread blocking on a lock held by the route planner's background work, and the block is re-triggered by incoming GPS location updates.

Steps to reproduce
Select an external routing engine (any ACTION_COMPUTE_TRACK_PROVIDER addon) as the router.
While moving (real GPS, or a moving mock provider delivering frequent fixes), open a saved point and tap Navigate to.
The route planner opens and the UI freezes for ~30 s (ANR). Afterwards start == destination and navigation cannot be started.
Note: the external engine answers the computeTrack request in well under 1 s (measured in the addon), so the delay is not the engine round-trip.

What the ANR traces show
ANR #1 — Subject: Input dispatching timed out (... RoutePlannerActivity (server) is not responding. Waited 5001 ms for FocusEvent)

The UI (main) thread is BLOCKED, waiting to acquire a lock that is held by a background worker thread running the route planner's compute work.
The main thread arrived at that lock from a GPS location callback: LocationListener.onLocationChanged → Locus's location handling → the route planner. So each incoming GPS fix makes the UI thread contend for the same lock the background worker is holding.
The background worker thread is Runnable (actively working) and holds the lock for the duration of a long operation, so the UI thread cannot proceed.
ANR #2 — Subject: Input dispatching timed out (... MainActivityMap (server) is not responding. Waited 5006 ms for MotionEvent)

The UI thread is BLOCKED in RoutePlannerActivity.onDestroy, waiting to acquire the route planner's route-points list, which is still held by the same background worker thread.
I.e. closing the planner also blocks the UI thread because the background compute is not finished / not cancelled and still owns the shared data.
In both cases the addon's own code is not on any thread in the trace - the external engine is idle at the time of the freeze.

Analysis
The route planner runs its compute/processing on a background thread that holds shared locks (the route-points list, and a settings/store object) across a long operation. Meanwhile the UI thread acquires those same locks - on every GPS onLocationChanged, on touch input, and in onDestroy. While driving, location fixes arrive roughly once per second, so the UI thread is repeatedly stalled behind the background worker → input dispatching times out → ANR. With a built-in router the contended window appears short enough to go unnoticed; with an external engine selected the planner stays in this state long enough to ANR, and the route ends up degenerate (start == destination).

Suggested fixes (for your consideration)
Don't hold the route-points list / settings-store lock across the long operation on the planner's background thread; snapshot under the lock, then process lock-free.
Make the planner's GPS onLocationChanged handling non-blocking — don't contend for the compute lock on the UI thread.
Cancel the planner's background work in onDestroy rather than blocking the UI thread on its lock.
The two full ANR traces (~1 MB each) are available on request.

Thank you for looking into that.
Title: Re: Custom router over API
Post by: Menion on June 22, 2026, 09:46:06
Thanks Trullo,
interesting how deeply you were able to trace the problem and almost correctly  :).

There really was one possible sync-lock that should be fixed now. So give a try to the next version. In case it still happens, the ANR log will be welcome.
Title: Re: Custom router over API
Post by: Tapio on June 22, 2026, 10:23:44
Quote from: Menion on June 22, 2026, 09:46:06interesting how deeply you were able to trace the problem and almost correctly  :).
How he even sounded like AI output - impressive😬
Title: Re: Custom router over API
Post by: Menion on June 22, 2026, 11:19:30
I know this is mostly AI output, and it is perfectly ok.

I'm just surprised how deeply Trullo, with the help of AI was able to go.
Title: Re: Custom router over API
Post by: TrulloF on June 22, 2026, 17:11:30
Quote from: Tapio on June 22, 2026, 10:23:44
Quote from: Menion on June 22, 2026, 09:46:06interesting how deeply you were able to trace the problem and almost correctly  :).
How he even sounded like AI output - impressive😬
Of course it's AI output, but if it helps to make the app better, fixing bugs in the process, then I'm gladly guilty of Ai slop. The addon I'm working on is the last missing link for me, to make Locus my only all-in-one navigation solution by providing traffic aware routing with the help of the free TomTom API. Works surprisingly well and is free.
Title: Re: Custom router over API
Post by: TrulloF on June 27, 2026, 12:31:47
Hi Menion,

Thanks for the lockup fixes in 4.35.0 (v1215). Unfortunately I hit the navigate-while-moving freeze again on a drive yesterday (2026-06-26). The signature is different from the earlier blocking-I/O ANRs, so I think one path remains.

Setup: Locus Map 4.35.0 (v1215), external routing addon active (my own ACTION_COMPUTE_TRACK_PROVIDER engine). Started navigation, Locus locked up and never recovered; I had to force-stop.

What the ANR shows (anr_locus_..._2159_navigate-while-moving.txt):

Main thread is Runnable and spinning (not blocked on I/O) — ~33 s of CPU on tid=1, process at 145% user CPU.
It's driven by a GPS update on the UI thread, holding two internal locks:
LocationListener.onLocationChanged
  → r20.d.onLocationChanged → f10.j.c
  → v20.a.f  (locked <0x...> v20.e)
  → ... → zt.c1.onEvent  (event bus)
  → ... → i70.d.j  (locked <0x...> i70.d)
  → com.google.android.gms.internal.ads.ec1.I/L/J → lp0.a0.b
Heap at the time: 4% free, 398MB/417MB, 12.08M objects, with heavy concurrent-copying GC (MarkingPhase sum ~9 s over 34 iterations) — so memory pressure may be feeding the spin.
This is distinct from the 2026-06-21 freezes (those were UI-thread blocking I/O in SQLite NativeDB.prepare / FilterInputStream.read). Here it's a compute/allocation spin in the per-location event handler — every GPS fix re-enters it, which fits "freezes while moving."

I've confirmed the routing addon is not involved: it returned the track in 698 ms and its name appears in no frame of either ANR, and the return leg of the same drive navigated for 24 minutes on the same engine without issue.

A second ANR from the same day (anr_locus_..._0025.txt, UI button press stalling in Resources.getInteger/AssetManager) is attached in case it's related.

Both files are the Locus process section only, with the device build fingerprint and APK install hashes redacted.

Thanks!

Attachments:
anr_locus_2026-06-26_2159_navigate-while-moving.txt (https://1drv.ms/t/c/e1b44d3b0e43ddff/IQC6xR3oUkM7T6xNQLGnW78xAWLAV5TXMGrzEHlytIVErvk?e=5GJ7mR)
anr_locus_2026-06-26_0025.txt (https://1drv.ms/t/c/e1b44d3b0e43ddff/IQCpw2KK7LinQ5_yAo0xEyyWAeGFH3rCodl7on9PT2Na3qs?e=pFI5eO)


This report was prepared with the help of Claude Code, which pulled and analyzed the ANR traces and the addon log, and redacted the attachments.
Title: Re: Custom router over API
Post by: Menion on June 29, 2026, 11:01:15
Thanks again. Let's AI chat with AI  ;)

I'm personally unable to simulate it, so more investigation is needed.



Good news first: the lockup you hit before (the UI thread blocked on a lock held by the background route computation) is genuinely fixed in 4.35.0. These two new ANRs are a different failure mode. In both traces the main thread isn't blocked waiting on a lock — it's runnable, and the managed (Dalvik) heap is essentially full: 0–4% free, ~380–417 MB, 11–12 million live objects, with 20–38 s of cumulative GC. That's a garbage-collection-thrash ANR: the heap is so full that GC eats every cycle and the app stalls on whatever the main thread happens to touch (a route-name geocode in one trace, a button press in the other — both just unlucky victims, not the cause).

We also confirmed on our side that ~30 minutes of steady navigation keeps the managed heap flat (~40 MB), which matches your return leg running 24 minutes cleanly. So this isn't guidance leaking over time — something specific is accumulating those ~12M objects, and the only way to know what is a heap dump from the bloated state.

Since your device is rooted, could you grab one?

Reproduce until the app is in the heavy state — ideally right after a navigate-while-moving freeze, or at the end of a drive like the one that froze.
Capture (root shell), forcing a GC first so the dump shows only retained objects:
su -c 'am dumpheap -g menion.android.locus /sdcard/Download/locus_heap.hprof'
(If the package name doesn't resolve, use the pid: pidof menion.android.locus, then am dumpheap -g <pid> /sdcard/Download/locus_heap.hprof.)
It'll be a few hundred MB — please zip it. Android Studio opens the am dumpheap output directly; for MAT it needs hprof-conv first, but we'll handle that.
One thing: a heap dump contains live in-memory data — coordinates, track and point names, possibly addresses — so please don't attach it to the public forum. Send it privately (a help-desk ticket attachment or a private file link is ideal) and we'll treat it as confidential.

And three quick questions to corroborate while you're at it:

Roughly how long had Locus been running before the freeze?
Around how many times did you start "Navigate to" / recompute a route in that session?
How large was the route/track involved (rough point count or distance)?
Title: Re: Custom router over API
Post by: TrulloF on June 29, 2026, 22:40:53
Let me try to answer without AI 😁. To reproduce the bug you'd need to be driving, while starting a new navigation from the point menu with an external routing provider activated.
It's also happening right after a fresh start of Locus, doesn't matter.
I created a workaround by starting navigation via the addon button in the point menu (non-AIDL path). Works instant and without lockup. As you have access to my github you could download the latest version, install and test for yourself. I'll test with a different phone these days, but I'm quite sure it's not a memory problem.
Title: Re: Custom router over API
Post by: TrulloF on July 06, 2026, 12:14:43
Ok, "your" AI was right. Problem was full heap on my testing device (Xperia XZ1 Compact). On a Xperia 10III the problem isn't present. I'll report back after more thorough testing, but looks like my "fix" needs to be a new phone.