Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jumping markers on Maps v2 #289

Closed
barbeau opened this issue Aug 31, 2015 · 16 comments
Closed

Jumping markers on Maps v2 #289

barbeau opened this issue Aug 31, 2015 · 16 comments
Labels
Milestone

Comments

@barbeau
Copy link
Member

barbeau commented Aug 31, 2015

For develop branch

I'm seeing markers jump around on the map on Android Maps API v2 even when nothing is happening in the app.

Here's a video of the behavior:

https://youtu.be/cOUGD0T5Ojs

What I expect

Markers should remain stationary at their originally added lat/long.

What steps will reproduce the problem?

or

  • 1b. Build, install, and run the develop branch of OneBusAway:
    • a. git clone https://github.com/OneBusAway/onebusaway-android.git
    • b. git checkout develop
    • c. gradlew installObaGoogleDebug
    • d. adb shell am start -n com.joulespersecond.seattlebusbot/org.onebusaway.android.ui.HomeActivity
    1. Browse to any supported city (e.g., Seattle or Tampa), and watch the green bus stop markers jump around on the map

I should add that I can't always reproduce this. It seems like everything works fine for a time, but then when the markers start jumping around they don't stop.

Marker Implementation Details

The code that loads the icons used for the 9 marker types (8 directions + no direction) is here:
https://github.com/OneBusAway/onebusaway-android/blob/develop/onebusaway-android/src/google/java/org/onebusaway/android/map/googlemapsv2/StopOverlay.java#L169

I'm using this drawable:
https://github.com/OneBusAway/onebusaway-android/blob/develop/onebusaway-android/src/main/res/drawable/map_stop_icon.xml

...which is a number of shapes - this creates the main green circle with the white outline and the drop shadoes. Then, I'm drawing the direction arrow on top of this drawable for each of the 8 directions - code for drawing directions is here:

https://github.com/OneBusAway/onebusaway-android/blob/develop/onebusaway-android/src/google/java/org/onebusaway/android/map/googlemapsv2/StopOverlay.java#L202

In the code to load the icons, I'm caching the BitmapDescriptor returned from BitmapDescriptorFactory.fromBitmap() for each of the 9 icon types on first load, so this isn't done each time a marker is put on the map.

I also saw the app crash to "Unfortunately, OneBusAway has stopped." and saw this exception in Logcat after letting the app sit on the map screen for a few minutes:

08-10 16:40:02.422  15843-15929/com.joulespersecond.seattlebusbot E/AndroidRuntime﹕ FATAL EXCEPTION: GLThread 8614
    Process: com.joulespersecond.seattlebusbot, PID: 15843
    java.lang.IllegalArgumentException: Comparison method violates its general contract!
            at java.util.ComparableTimSort.mergeHi(ComparableTimSort.java:831)
            at java.util.ComparableTimSort.mergeAt(ComparableTimSort.java:449)
            at java.util.ComparableTimSort.mergeCollapse(ComparableTimSort.java:372)
            at java.util.ComparableTimSort.sort(ComparableTimSort.java:178)
            at java.util.ComparableTimSort.sort(ComparableTimSort.java:142)
            at java.util.Arrays.sort(Arrays.java:1957)
            at java.util.Collections.sort(Collections.java:1864)
            at com.google.maps.api.android.lib6.gmm6.n.bl.a(Unknown Source)
            at com.google.maps.api.android.lib6.gmm6.n.l.a(Unknown Source)
            at com.google.maps.api.android.lib6.gmm6.n.l.b(Unknown Source)
            at com.google.maps.api.android.lib6.gmm6.n.cv.f(Unknown Source)
            at com.google.maps.api.android.lib6.gmm6.n.cv.run(Unknown Source)

I've seen this on an LG G4 and Nexus 6. More details on LG device is below.

  • LG G4 LS991 with Android 5.1 (LS991ZV4)
  • Google Play Services client library version = compile 'com.google.android.gms:play-services-maps:7.5.0' and compile 'com.google.android.gms:play-services-maps:7.8.0'
  • Google Play Services version on the device - Google Play Services 7.8.99 (2134222-440)
  • Android SDK Version: compileSdkVersion 21 buildToolsVersion "21.1.2"

This issue hasn't always existed, which makes me believe it was introduced during an update to Android Google Play Services/Maps at some point.

I've opened an issue for this on gmaps-api-issues as well, but no response as of this post:

https://code.google.com/p/gmaps-api-issues/issues/detail?id=8455

I've created a smaller demo project here on Github that uses the same marker implementation:

https://github.com/barbeau/maps-demo

...but so far I haven't been able to reproduce the problem there.

@barbeau barbeau added the bug label Aug 31, 2015
@barbeau
Copy link
Member Author

barbeau commented Aug 31, 2015

I've also posted to StackOverflow on this problem:
http://stackoverflow.com/questions/32276570/jumping-markers-on-android-maps-api-v2

There have been a few upvotes so far, so I guess we're not the only ones seeing this.

barbeau added a commit that referenced this issue Aug 31, 2015
* Resources.getDrawable() is deprecated starting with API Level 22
* See http://stackoverflow.com/questions/29041027/android-getresources-getdrawable-deprecated-api-22
* This could potentially be related to #289 - maybe this fixes it?
@barbeau
Copy link
Member Author

barbeau commented Aug 31, 2015

And a post to the Google+ Android Developers community:
https://plus.google.com/u/0/+SeanBarbeau/posts/RrSYWxy7NUt

@barbeau
Copy link
Member Author

barbeau commented Aug 31, 2015

I just pushed 01b35e9 to the develop branch, which changes to caching Bitmaps instead of BitmapDescriptors for map icons. If Maps API v2 implementation is doing some kind of recycling of BitmapDescriptors this could potentially fix the problem.

@cagryInside could you start running this on your Nexus 6 and let me know if you see the problem again?

I can't always consistently reproduce this on the LG G4, as its intermittent. So, I can't really saw whether or not this commit conclusively fixed the problem yet, unless neither of us see the issue again after a period of time.

@barbeau
Copy link
Member Author

barbeau commented Sep 1, 2015

I'm still seeing the problem, so looks like switching from caching BitmapDescriptors to Bitmaps, and changing to using ContextCompat.getDrawable(), didn't have any effect.

@cagryInside
Copy link
Contributor

@barbeau Just checked with my nexus 6, I don't see the problem. But, I rolled back the latest development, I still don't see the problem. So, I don't think it did any effect.

@barbeau
Copy link
Member Author

barbeau commented Sep 1, 2015

Yeah, this one has been tricky to reproduce. After doing a new debug install it doesn't always happen right away. Seems like after a while something breaks in the Maps API implementation, and after this happens then the jumping markers persist for a while. It also seems to happen per-app - last night I saw the issue in OBA, and switched to the maps-demo project I created, but didn't see the issue in that app.

@barbeau
Copy link
Member Author

barbeau commented Sep 23, 2015

I haven't seen this issue lately, and I noticed that Google Play services on my device was bumped to 8.1.15. So, maybe it was fixed with an update of Google Play services?

@cagryInside (or anyone else) - if you see this problem again, please let me know, and let me know which version of Google Play services your device has.

@barbeau barbeau added this to the Public v2.0.x release milestone Sep 24, 2015
@barbeau
Copy link
Member Author

barbeau commented Sep 25, 2015

Talking to @cagryInside today, he hasn't seen this on his Nexus 6 recently either - currently running Play Services 8.1.15. I'm going to close this for now, and will re-open if we see the problem again.

@barbeau barbeau closed this as completed Sep 25, 2015
@barbeau
Copy link
Member Author

barbeau commented Sep 29, 2015

Just saw this again - I think it may be triggered by stacking multiple Activities that use the map on top of each other, and then closing them by hiting the back button.

There is a new version of Play Services available in the build tools, we should try this.

@barbeau barbeau reopened this Sep 29, 2015
@barbeau
Copy link
Member Author

barbeau commented Oct 9, 2015

I'm still seeing this after bumping Play Services to 8.1.0 in build.gradle. It's more subtle than its been in the past - sometimes the shift of the markers is just changes in the Z-order, with the position unchanged. But, jumping of markers to places where there shouldn't be markers can still be seen.

@barbeau
Copy link
Member Author

barbeau commented Oct 29, 2015

For the current develop branch, if you tap on an arrival time and select the option to "Show route on map", let the map with vehicle positions load, and then change the orientation of the screen to landscape, this seems to trigger the behavior every time I've tried it, and really bad - they jump all over the screen. Here's a video screen capture:
https://youtu.be/gYBunJYZTMo

Strangely, if you return back to portrait orientation, the jumping stops, and everything goes back to normal.

This is still using Play Services to 8.1.0 in build.gradle, and Play Services 8.3.00 (2353383-240) on an LG G4 w/ Android 5.1.

@barbeau
Copy link
Member Author

barbeau commented Oct 29, 2015

Interestingly, if you start with the arrival screen in landscape mode, and then tap on "Show route on map" so this route mode map screen loads in landscape, the markers don't jump around. And, if you switch to portrait while on that screen, the markers also don't jump around. But, if you change the orientation back to landscape, then the markers start jumping. So the orientation change from portrait to landscape while viewing the route mode on map seems to trigger the jumping, but never landscape to portrait.

@barbeau
Copy link
Member Author

barbeau commented Nov 6, 2015

Play Services 8.3 was released today, so just bumped Play Services to 8.3.0 in build.gradle in 77804b8. No effect on this issue - when switching route mode to landscape orientation I still see the markers jump around the screen.

@barbeau
Copy link
Member Author

barbeau commented Nov 6, 2015

AFAIK there isn't anything we can do to prevent this issue - it just happens. So, I'm going to leave it open but push it to a future milestone. Under normal use/conditions it doesn't seem bad/frequent enough to block a public v2.0 release. But, we should continue to track it.

@barbeau barbeau modified the milestones: v2.1, Public v2.0.x release Nov 6, 2015
@barbeau
Copy link
Member Author

barbeau commented Nov 25, 2015

Whoops, this was automatically close by Github in the merge to master.

@barbeau barbeau reopened this Nov 25, 2015
@barbeau
Copy link
Member Author

barbeau commented Dec 11, 2015

This issue may have been fixed by 1fe8756, which fixed a leak of the BaseMapFragment (which extends the SupportMapFragment).

From my SO post (http://stackoverflow.com/a/34227146/937715):

I think this is definitely related to multiple instances of the SupportMapFragment existing simultaneously. In v2.0.6 I wasn't handling fragments correctly when the Activity was destroyed and recreated with a savedInstanceState (i.e., when the Activity was killed after being in background for a while, or on orientation change).

In v2.0.6, my code looked something like this:

public class HomeActivity ...{

    BaseMapFragment mMapFragment;

    ...

    private void showMap() {
        FragmentManager fm = getSupportFragmentManager();
        if (mMapFragment == null) {
                mMapFragment = BaseMapFragment.newInstance();
                fm.beginTransaction()
                    .add(R.id.main_fragment_container, mMapFragment)
                    .commit();
        }
    }
    ...
}

So, I was leaking an instance of BaseMapFragment (which extends SupportMapFragment) in those cases - an instance already existed in the FragmentManager, but I didn't have a local reference to it. I actually noticed this issue when Action Bar menu items were being duplicated for another fragment I was handling similarly.

I changed the code to look something like this, which first checks to see if the FragmentManager has an existing BaseMapFragment:

public class HomeActivity ...{

    BaseMapFragment mMapFragment;

    ...

    private void showMap() {
        FragmentManager fm = getSupportFragmentManager();            
        // First check to see if an instance of BaseMapFragment already exists            
        mMapFragment = (BaseMapFragment) fm.findFragmentByTag(BaseMapFragment.TAG);

        if (mMapFragment == null) {
            mMapFragment = BaseMapFragment.newInstance();
            fm.beginTransaction()
                    .add(R.id.main_fragment_container, mMapFragment, BaseMapFragment.TAG)
                    .commit();
        }
    }
    ...
}

The UI flow has changed in the master branch (I'm no longer opening a new Activity to view the route), so I can't directly test there if the problem is still reproducible after this code change.

However, I created this branch, which is branched from master but changed to have the same UI flow as v2.0.6, and includes the above fix for the fragment leak:

https://github.com/CUTR-at-USF/onebusaway-android/tree/jumpingMarkersTest

From some quick testing with this branch, it seems that handling the fragments correctly on orientation change (i.e., not leaking the fragment) may have fixed the jumping markers issue - at least using the steps above it no longer reproduces on a LG G4 with Android 5.1.

I'm going to close this for now, and will re-open if I see it again.

@barbeau barbeau closed this as completed Dec 11, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants