在Android Maps API v2上跳转标记

即使在应用程序中没有发生任何事情,我也可以在Android Maps API v2上看到地图上的标记。

这里是一个行为的video:

我期望的

标记应保持原来添加的经纬度不变。

哪些步骤将重现该问题?

  • 1A。 从以下url下载APK: https : //dl.dropboxusercontent.com/u/46443835/OneBusAway/UI_redesign/onebusaway-android-oba-google-debug.apk

要么

  • 1B。 构build,安装并运行OneBusAway的v2.0.6标签:

    • 一个。 git clone https://github.com/OneBusAway/onebusaway-android.git
    • git checkout v2.0.6
    • C。 gradlew installObaGoogleDebug
    • d。 adb shell am start -n com.joulespersecond.seattlebusbot/org.onebusaway.android.ui.HomeActivity
    1. 浏览任何受支持的城市(例如,西雅图或坦帕),并观看绿色的公共汽车站标记在地图上跳来跳去

我应该补充一点,我不能总是重现这一点。 看起来一切正常,但是当标记开始跳跃时,它们并没有停下来。

标记实现细节

加载用于9种标记types(8个方向+无方向)的图标的代码在这里: https : //github.com/OneBusAway/onebusaway-android/blob/master/onebusaway-android/src/google/java/组织/ onebusaway /安卓/地图/ googlemapsv2 / StopOverlay.java#L175

我使用这个drawable: https : //github.com/OneBusAway/onebusaway-android/blob/master/onebusaway-android/src/main/res/drawable/map_stop_icon.xml

…这是一些形状 – 这创造了白色轮廓和阴影的主要绿色圆圈。 然后,我在8个方向的每个方向上画出方向箭头 – 绘制方向的代码在这里:

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

在加载图标的代码中,我对第一次加载的9种图标types中的每一种都caching从BitmapDescriptorFactory.fromBitmap()返回的BitmapDescriptorFactory.fromBitmap() ,所以每次在地图上放置一个标记时都不会这样做。

我也看到了应用程序崩溃,“不幸的是,OneBusAway已经停止”。 并在让应用程序坐在地图屏幕上几分钟后,在Logcat中看到这个exception:

 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.nla(Unknown Source) at com.google.maps.api.android.lib6.gmm6.nlb(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) 

我已经在LG G4和Nexus 6上看到了这一点。关于LG设备的更多详情如下。

  • LG G4 LS991与Android 5.1(LS991ZV4)

  • Google Play服务客户端库版本= compile 'com.google.android.gms:play-services-maps:7.5.0'compile 'com.google.android.gms:play-services-maps:7.8.0'

  • Google Play服务版本 – Google Play服务7.8.99(2134222-440)

  • Android SDK版本: compileSdkVersion 21 buildToolsVersion "21.1.2"

这个问题并不总是存在,这让我相信它是在Android的Google Play服务/地图更新过程中引入的。

我已经在gmaps-api-issues上为此打开了一个问题,但是对于这篇文章没有回应:

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

有没有人看过这个? 任何想法修复?

编辑

我应该补充一点,我不能总是重现这一点。 看起来一切正常,但是当标记开始跳跃时,它们并没有停下来。

编辑2

我在Github上创build了一个使用相同标记实现的更小的演示项目:

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

但是,我还没有看到同样的问题。

编辑3

在https://github.com/OneBusAway/onebusaway-android/commit/01b35e9a07313a627843819d66b3f6a9bb7e848f中,我更改为cachingBitmaps而不是BitmapDescriptors

我们会看看这是否解决了这个问题。 这是间歇性的,所以我知道的唯一方法就是如果我在一段时间内没有再看到问题。

编辑4

我仍然看到问题,所以看起来像从cachingBitmapDescriptors切换到Bitmaps ,并改变使用ContextCompat.getDrawable() ,没有任何效果。

编辑5

不知道这是否是相关的,但是当发生这种情况时,我也在Logcat中看到以下输出:

09-01 10:46:00.339 9278-9278 /? E / libEGL:validate_display:255错误3008(EGL_BAD_DISPLAY)09-01 10:46:00.339 9278-9278 /? E / libEGL:validate_display:255错误3008(EGL_BAD_DISPLAY)

9-01 10:46:00.069 9278-9278 /? W / ResourcesManager:资产path“/system/framework/com.google.android.maps.jar”不存在或不包含任何资源。

09-01 10:46:16.019 1137-4311 /? W / ActivityManager:在1000ms内调度崩溃的服务com.google.android.gms / .usagereporting.service.UsageReportingService的重新启动09-01 10:46:16.019 1137-4311 /? W / ActivityManager:计划在11000毫秒内重新启动崩溃的服务com.google.android.gms / .icing.service.IndexService

09-01 10:48:38.609 5402-26676 /? E / SQLiteDatabase:错误插入context_name = 8 end_time = 1441118918490 context_family = 7 module_id = com.google.android.contextmanager.module.PowerConnectionModule version = 1 sync_state_mod_time_millis = 1441118918532 start_time = 1441118643058 sync_state = 0 context_id = 9680c4f4-789a-4d86-acbf-在android.database.sqlite android.database.sqlite.SQLiteConnection.nativeExecuteForLastInsertedRowId(本地方法)上的UNIQUE约束失败:context.context_id(代码2067)时间戳types= 3。 SQLiteConnection.executeForLastInsertedRowId(SQLiteConnection.java:790)在android.database.sqlite.SQLiteSession.executeForLastInsertedRowId(SQLiteSession.java:926)在android.database.sqlite.SQLiteStatement.executeInsert(SQLiteStatement.java:86)在android.database.sqlite .SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1581)at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1451)at com.google.android.cont (sourceFile:405)com.google.android.contextmanager.q.ak.b(SourceFile:380)at com.google.android.contextmanager.q.ak.a(SourceFile:346) at com.google.android.contextmanager.q.ak.b(SourceFile:373)at com.google.android.contextmanager.gaja(SourceFile:58)at com.google.android.contextmanager.gaarun(SourceFile:52)at com.google.android.contextmanager.gihandleMessage(SourceFile:214)at android.os.Handler.dispatchMessage(Handler.java:102)at android.os.Looper.loop(Looper.java:135)at android.os.HandlerThread .RUN(HandlerThread.java:61)

编辑6我最近还没有看到这个问题,我注意到在LG G4设备上的Google Play服务被碰撞到8.1.15 (2250156-240) 。 那么,也许它已经修复了Google Play服务的更新? 我稍后再报告。

编辑7我已经在8.1.15 (2250156-240)8.1.18 (2272748-240)再次看到这一点,虽然它看起来不像以前那么糟糕(即,更less的标记8.1.18 (2272748-240) ,跳跃不太明显)。 它似乎主要是当它在后台一段时间后恢复应用程序触发。 如果我杀了应用程序,然后重新启动它,问题就会消失。

编辑8我发现了一种方法来一贯重现这一点 – 请参阅: https : //code.google.com/p/gmaps-api-issues/issues/detail?id=8455#c2

从上面的问题:

  1. 构build,安装并运行OneBusAway的v2.0.6标签:

    一个。 git clone https://github.com/OneBusAway/onebusaway-android.git

    湾 git checkout v2.0.6

    C。 gradlew installObaGoogleDebug

    d。 adb shell am start -n com.joulespersecond.seattlebusbot / org.onebusaway.android.ui.HomeActivity

  2. 以纵向方向握住设备

  3. 如果您在西雅图或坦帕(或任何受支持的区域)没有物理位置,则需要转到“设置 – >您的区域”并手动设置区域。 完成后,将地图滚动到该地区(或者在提示时select“带我去”)。
  4. 点击地图上的巴士站
  5. 点击抵达时间旁边的3个“更多”button(或点击滑动面板上的列表中的点击)
  6. 点击选项“在地图上显示路线”
  7. 在地图上加载路线后,将设备方向更改为横向。
  8. 在地图重新加载之后,观察标记跳转

LG G4上的完整video截图显示了制作和发布的新步骤: https : //youtu.be/oiBoMTPDVrU

Solutions Collecting From Web of "在Android Maps API v2上跳转标记"

我认为这肯定与同时存在的多个SupportMapFragment实例有关。 在v2.0.6 ,当Activity被销毁并用savedInstanceState重新创build时(即当Activity在后台被杀死一段时间后,或者在方向改变时),我没有正确地处理片段。

v2.0.6 ,我的代码看起来像这样:

 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(); } } ... } 

所以,在这种情况下,我泄露了一个BaseMapFragment (它扩展了SupportMapFragment )的实例 – 一个已经存在于FragmentManager的实例,但是我没有一个本地引用。 我实际上注意到这个问题时,行动酒吧菜单项被重复我正在处理类似的另一个片段。

我改变了代码,看起来像这样,它首先检查是否FragmentManager有一个现有的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(); } } ... } 

主stream分支中的UIstream已经改变了(我不再打开一个新的活动来查看路由),所以如果在这个代码改变之后问题仍然是可重现的,我不能直接testing那里。

但是 ,我创build了这个分支,它是从主分支,但改为具有相同的用户界面stream程v2.0.6,并包括上述修复碎片泄漏:

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

从这个分支的一些快速testing,似乎正确地处理方向变化(即不泄漏的片段) 可能已经修复了跳跃标记问题 – 至less使用上面的步骤不再再现LG G4 Android上5.1。