对不起我的英语不好

我尝试了ClusterManager<?>.getMarkerCollection().getMarkers()方法,但它返回空集合。

我在我的应用程序中使用Google Maps Utility Library。每次屏幕旋转后,我都会创建AsynkTask,并在后台线程中从DB读取数据并将项目添加到ClusterManager:

cursor.moveToFirst();
while (!cursor.isAfterLast()) {
    SomeData row = readSomeDataRow(cursor);
    clusterManager.addItem(new ClusterItemImpl(row));
    cursor.moveToNext();
}

AsyncTask完成工作时(即在主线程中),我尝试从ClusterManager获取所有标记:
clusterManager.cluster();
// cluster manager returns empty collection  \|/
markers = clusterManager.getMarkerCollection().getMarkers();

ClusterManager返回空集合。

可能是在我将getMarkers()称为ClusterManager的那一刻,但尚未将标记放置在 map 上,稍后会做(可能在后台线程中)。如果是这样,那我该如何捕获那一刻?

最佳答案

我会给你一个很好的解决方法。首先,我将提供一些背景知识。然后,我将告诉您修改代码的非常简单的方法。

背景:让我们首先从库代码中查看ClusterManager.addItem的实现:

public void addItem(T myItem) {
    this.mAlgorithmLock.writeLock().lock();

    try {
        this.mAlgorithm.addItem(myItem);
    } finally {
        this.mAlgorithmLock.writeLock().unlock();
    }

}

如您所见,当您调用clusterManager.addItem时,ClusterManager随后将调用this.mAlgorithm.addItem。 mAlgorithm是存储项目的位置。现在让我们看一下ClusterManager的默认构造函数:
public ClusterManager(Context context, GoogleMap map, MarkerManager markerManager) {
    ...
    this.mAlgorithm = new PreCachingAlgorithmDecorator(new  NonHierarchicalDistanceBasedAlgorithm());
    ...
}

mAlgorithm实例化为包含NonHierarchicalDistanceBasedAlgorithm的PreCachingAlgorithmDecorator。不幸的是,由于mAlgorithm被声明为私有(private),因此我们无权访问正在添加到算法中的项。但是,很高兴有一个简单的解决方法!我们仅使用ClusterManager.setAlgorithm实例化mAlgorithm。这使我们可以访问算法类。

解决方法:这是插入了替代方法的代码。
  • 将此声明与您的类变量一起放置:
    private Algorithm<Post> clusterManagerAlgorithm;
    
  • 在实例化ClusterManager的地方,此后立即放置:
     // Instantiate the cluster manager algorithm as is done in the ClusterManager
     clusterManagerAlgorithm = new NonHierarchicalDistanceBasedAlgorithm();
    
     // Set this local algorithm in clusterManager
     clusterManager.setAlgorithm(clusterManagerAlgorithm);
    
  • 您可以完全相同地保留用于将项目插入集群的代码。
  • 当您想访问插入的项目时,只需使用与ClusterManager相反的算法即可:
    Collection<ClusterItemImpl> items = clusterManagerAlgorithm.getItems();
    

  • 这将返回项目而不是Marker对象,但是我相信这是您所需要的。

    10-06 03:14