openbmap / radiocells-scanner-android

WLAN and cell tower scanner for Radiocells.org
https://www.radiocells.org
Other
57 stars 25 forks source link

Autosplit the current session #92

Open sim6 opened 9 years ago

sim6 commented 9 years ago

Hello,

Fisrtly, thanks for your work.

When Radiobeacon Android client has scanned hundreds of WiFi cells during the current session it becomes slowly and eats my battery. Please, could you add a feature to split the current session automatically?

Thanks again.

wish7code commented 9 years ago

Hey Simó,

short update on this one: I assume this happens in map display mode, right? I analyzed the code and found some potential memory leaks..

As soon as I get the remaining issues in the nightly builds fixed, I'll update F-Droid release..

Cheers Toby

sim6 commented 9 years ago

No, I don't use the map. I start a new session and the overview is displayed, then I lock the phone. If it scans more than 500 wifis then when I want to restoring the application takes too long to display the overview again.

mvglasow commented 8 years ago

Same thing here. It is easiest to observe in map display mode, as updates take really long (and it also seems to have an impact on measurements). However, I've also observed it in overview screen when tracking with two devices, one of which had a fresh session while the other one had been tracking for a while.

Today I had the issue again. I stopped tracking and restarted, to no avail. Then, I killed the app (with a long press of the Back key), restarted it and resumed the session, and things slowed down again within a few seconds. That means it is really the size of the current session that matters, not the time spent logging.

About autosplit – if you decide to take that path, there's the map display issue. I rely heavily on the map (to check where I've already been), thus we need a way to ensure the first part of the session doesn't suddenly disappear from the map when the session is split.

wish7code commented 8 years ago

Since it happens not only in map mode, as Simó observed, I was wondering whether this may be related to the 'not-so-smart' way we currently handle status bar updates :-(

We've got some potentially heavy database operations to count current session's number of wifis @ https://github.com/wish7code/openbmap/blob/master/android/app/src/main/java/org/openbmap/activities/StatusBar.java#L153 . This line is called on each and every observed wifi and opens a database cursor @ https://github.com/wish7code/openbmap/blob/master/android/app/src/main/java/org/openbmap/db/DataHelper.java#L176

We might simply put to much pressure on the database by doing this...

Instead I think we should cache the number of wifis in the activity and remove the database access at this point

mvglasow commented 8 years ago

That should be fairly easy to detect – call System.nanoTime() before and after the operation to measure duration. If it's the DB operations, we should see the duration for these queries start out small, then grow in duration as the session gets larger.

As for the counter – the main challenge I see is deduplication. Assuming you have just picked up BSSID 00:0b:ad:c0:ff:ee, then move out of its range and at a later point pick it up a second time: you want to make sure we don't count it again. For the count of new wifis, this is even more important.

Therefore, we'll probably still need to do two database queries for each wifi in a scan result:

Without having looked through the code in detail, the second query is probably already there, and it shouldn't cause any performance issues – if it did, they'd appear right at the start of each session. The first query could be modeled after it. Rather than selecting all matching rows, you might want to use EXISTS, which is potentially faster (the DBMS can stop searching after the first hit).

I had a look at indices: I see there is already an index on wifis(session_id) and on wifis(bssid, level) (the latter of which will also work for lookups by bssid).

Running

explain query plan select * from wifis where bssid='00:0b:ad:c0:ff:ee' and session_id = 42;

returns

SEARCH TABLE wifis USING INDEX idx_wifis_sessions_id (session_id=?)

which means the query walks through all the wifis in the current session. I'd suggest extending the index on wifis(session_id) to wifis(session_id, bssid): it would still work for lookups by session_id only (session_id being the first column in the index) but also speed up queries like the above.

mvglasow commented 8 years ago

I've extended the index as described in my local Radiobeacon db and will see how that affects behavior. After my next longer log, I'll report back.

mvglasow commented 8 years ago

I went on a longer logging trip today and it looks as if the index alone doesn't help – at around 3000 wifis map updates slowed down noticeably. After I started a new session, everything was fine again.

wish7code commented 8 years ago

I know this is a long time issue, but by instance I discovered something really strange today:

I started RadioBeacon without no local map installed. In that case RadioBeacon falls back to using online maps.

Right now I've got a session with ~5000 wifis and no observable lag. So it might be a bug related to mapsforge offline maps?

Coud anybody verify this behaviour?

mvglasow commented 8 years ago

RadioBeacon falls back to using online maps

Interesting... didn't know that was possible. Is there a way I can choose between online and offline maps? (If not, that would be a feature request... most of the functionality is probably there already.)

If it really is mapsforge (and only when maps are rendered locally), I do find it somewhat surprising that this also appears to happen when overview is active (afaik Android keeps only the active page and its immediate neighbors around, thus the map page wouldn't even get created until I switch to its imediate neighbor).

I'll try one thing when I have the chance to: I'll disable map centering so that position changes will not trigger rendering operations, and then see what happens.

If it really turns out to be a mapsforge issue, the guys there appreciate it when you can give them steps to reproduce the behavior with their sample app, though that might be difficult here. Maybe plugging into Mapsforge's test harness is the way to go here: request a handful of tiles to be rendered over and over again, and watch rendering times – they should not change noticeably.

wish7code commented 8 years ago

If not, that would be a feature request

Makes perfect sense, Greg already open a feature request, see #153

afaik Android keeps only the active page and its immediate neighbors around

Correct, but unfortunately it's seems to be impossible to deactivate that caching completely. To make it worse, I think I remember that sometimes Android gets confused on what is the immediate neighbor to load after switching tabs. So the map component might be loaded even though it's not a immediate neighbor.

mvglasow commented 8 years ago

I recently learned through painful experience that certain Mapsforge components require cleanup when they are no longer needed – not doing so will eventually exhaust all available memory – I haven't studied the exact behavior, but since an app with a memory leak would require more and more memory, the system may need to do stuff in the background (kill apps in the background, start garbage collections etc.) which would consume processing power, slowing it down.

In the onDestroy() method of your Activity or Fragment, call the following:

More important, every time you remove a layer from the map view, you need to call onDestroy() on it. IIRC, Radiobeacon creates layers dynamically for the overlays – could that be the issue? Maybe watching memory usage of the app over time would help.

mvglasow commented 8 years ago

I upgraded from 0.8.15 to 0.8.18 last week, and the new version exhibits this behavior after just a few minutes of tracking.

I have tested this in two setups:

Which leads me to the two suspicions: