【发布时间】:2016-06-05 03:47:17
【问题描述】:
我在 ListView 中有一个 MapView(精简模式)。这是按照以下示例中的方法完成的: https://github.com/googlemaps/android-samples/blob/master/ApiDemos/app/src/main/java/com/example/mapdemo/LiteListDemoActivity.java
此 MapView 的 XML 代码如下所示:
<com.google.android.gms.maps.MapView android:id="@+id/mapLocation"
android:layout_width="match_parent"
android:layout_height="@dimen/google_map_height"
map:liteMode="true"
map:mapType="none"
android:layout_below="@+id/textTitle"
android:visibility="gone"
android:padding="@dimen/image_padding"
android:apiKey="AIzaSyBDOINR0EcGYu9RDUY1******"/>
第一次加载地图时,我能够放置一个标记并正确设置相机。一切看起来都很正常,ListView 的滚动看起来很流畅。当用户单击 MapView 时,它还能够生成 onMapClick() 事件。但是,稍后当我尝试使用以下代码移动标记或重置相机视图时,MapView 挂起:
// Update GUI
boolean hasLocation = (targetLatLng != null);
MapView mapView = (MapView) view.findViewById(R.id.mapLocation);
if (mapView != null) {
if (hasLocation) {
mapView.setVisibility(View.VISIBLE);
if (listViewGoogleMap != null) {
listViewGoogleMap.moveCamera(
CameraUpdateFactory.newLatLngZoom(targetLatLng, 13f));
// if (markerListViewMap != null)
// markerListViewMap.setPosition(targetLatLng);
// else
// markerListViewMap = listViewGoogleMap.addMarker(new MarkerOptions()
// .position(targetLatLng));
} else {
mapView.setVisibility(View.GONE);
}
}
}
请注意,我已经注释掉了 Marker.setPosition() 部分,该部分用于在地图上移动标记。如果我同时注释掉 moveCamera() 语句和 Marker.setPosition() 部分,则不再发生挂起。
发生挂起时,MapView 不再响应鼠标点击(不触发 onMapClick() 事件)。 ListView 的滚动变得明显迟缓。此外,调试日志中还会出现大量关于 CPU 和内存消耗的警告:
06-05 10:35:55.731 11672-11672/cards.myb.mybusinesscards D/CardEditorMapRow: Longitude/latitude obtained from dialog : (23.0238082, 120.2276839)
06-05 10:35:55.731 11672-11672/cards.myb.mybusinesscards D/CardEditorMapRow: Address obtained from dialog:
06-05 10:35:56.557 11672-11683/cards.myb.mybusinesscards I/art: Background sticky concurrent mark sweep GC freed 626(33KB) AllocSpace objects, 5(13MB) LOS objects, 22% free, 46MB/59MB, paused 21.757ms total 32.972ms
06-05 10:35:57.653 11672-11678/cards.myb.mybusinesscards W/art: Suspending all threads took: 11.688ms
06-05 10:35:58.155 11672-11678/cards.myb.mybusinesscards W/art: Suspending all threads took: 13.849ms
06-05 10:35:58.410 11672-11683/cards.myb.mybusinesscards I/art: Background partial concurrent mark sweep GC freed 701(35KB) AllocSpace objects, 10(16MB) LOS objects, 26% free, 43MB/59MB, paused 5.653ms total 28.354ms
06-05 10:35:58.551 11672-11683/cards.myb.mybusinesscards I/art: Background sticky concurrent mark sweep GC freed 587(32KB) AllocSpace objects, 5(13MB) LOS objects, 22% free, 46MB/59MB, paused 10.637ms total 20.616ms
06-05 10:36:00.283 11672-11683/cards.myb.mybusinesscards I/art: Background partial concurrent mark sweep GC freed 791(40KB) AllocSpace objects, 11(19MB) LOS objects, 26% free, 43MB/59MB, paused 9.291ms total 34.966ms
06-05 10:36:01.802 11672-11683/cards.myb.mybusinesscards I/art: Background partial concurrent mark sweep GC freed 833(42KB) AllocSpace objects, 11(19MB) LOS objects, 26% free, 43MB/59MB, paused 5.594ms total 31.557ms
06-05 10:36:04.676 11672-11678/cards.myb.mybusinesscards W/art: Suspending all threads took: 18.995ms
一种解决方法是重新创建整个活动。 (再次隐藏和显示 MapView 无济于事)感谢任何 cmets!
2016 年 6 月 6 日编辑: 经过进一步调试后,我意识到这是由于某种与 MapView 组件相关的无限循环。在每次 MapView 的 ViewTreeObserver 调用 OnGlobalLayout() 时添加一条显示调试消息的语句后,我看到 数千 条消息(并且还在计数......),如下所示:
06-06 06:39:48.532 11208-11208/cards.myb.mybusinesscards D/CardEditorMapRow:
onGlobalLayout() count=2681
06-06 06:39:48.581 11208-11208/cards.myb.mybusinesscards D/CardEditorMapRow:
onGlobalLayout() count=2682
06-06 06:39:48.658 11208-11208/cards.myb.mybusinesscards D/CardEditorMapRow:
onGlobalLayout() count=2683
06-06 06:39:48.688 11208-11219/cards.myb.mybusinesscards I/art: Background
sticky concurrent mark sweep GC freed 511(27KB) AllocSpace objects, 4(10MB)
LOS objects, 16% free, 53MB/64MB, paused 10.956ms total 23.201ms
06-06 06:40:04.141 11208-11208/cards.myb.mybusinesscards D/CardEditorMapRow:
onGlobalLayout() count=2684
06-06 06:40:04.183 11208-11208/cards.myb.mybusinesscards D/CardEditorMapRow:
onGlobalLayout() count=2685
06-06 06:40:04.212 11208-11208/cards.myb.mybusinesscards D/CardEditorMapRow:
onGlobalLayout() count=2686
【问题讨论】:
-
您的垃圾收集器调用可能会挂起您的主线程。这是因为回收视图时正在释放 MapView 资源。检查那可能是地图标记还是地图视图本身。
-
谢谢!你的观点很好。我沿着这条线做了一些进一步的检查。实际上,在 onGlobalLayout() 调用之间有很多 ListAdapter.getView() 调用和 onMovedToScrapHeap() 调用。不过,这个问题似乎很复杂,因为我的 ListView 中的每一行都有不同的布局。我需要对此进行更多调查..
标签: android google-maps listview android-mapview