我的开发团队和我在Xamarin项目的Android发行版中遇到问题。问题是这样的:应用程序使用对象的可观察集合,并以列表视图和带有代表对象的图钉的地图视图的形式表示这些对象。在地图视图中,我们的代码旨在订阅消息传递中心调用,该调用会定期更新API(项目的其他部分)中可观察到的对象集合。我们遇到的问题是,当我们在消息传递中心代码块中调用PlotPins方法时,应用程序应首先检索更新的列表,然后访问该列表以在地图上绘制图钉。每次收到更新时,应用程序都会从映射中清除所有引脚,然后根据更新后的列表重新绘制引脚(我们知道效率低下,但这是一个临时解决方案)。但是,引脚永远不会更新。通过使用调试器,我们发现,一旦调用PlotPins()中的map.Pins.Clear(),应用程序就会跳转到RequestUpdatedListAsync方法的末尾(该过程定期发生以检索更新的列表,并触发消息中心。 ),然后停止。
我们的解决方案适用于我们的GTK构建,其销钉已按预期清除并重新绘制在地图上,因此这似乎是Android特有的问题。
任何帮助,谢谢。
位于下面的相关代码:
邮件中心:
MessagingCenter.Subscribe<object, ObservableCollection<MyObject>>(Application.Current, Constants.ListUpdateContract, (sender, newList) =>
{
//update list
listUpdater.UpdateList(newList);
//call method to plot pins again
PlotPins(map);
});
图钉:
private void PlotPins(Map map)
{
map.Pins.Clear();
foreach (MyObject in MyObjects)
{
var pin = new Pin
{
Label = MyObject.ID,
Address = "Latitude: " + MyObject.Latitude + " " + "Longitude: " + MyObject.Longitude,
Type = PinType.Place,
Position = new Position(Convert.ToDouble(MyObject.Latitude), Convert.ToDouble(MyObject.Longitude))
};
//event handler for when user clicks on pin's info window
pin.InfoWindowClicked += async (s, args) =>
{
//opens up detail page for pin associated with myObject
await Navigation.PushAsync(new DetailPage(MyObject));
};
map.Pins.Add(pin);
}
}
请求更新列表异步:
public static async System.Threading.Tasks.Task<bool> RequestUpdatedListAsync()
{
if (!_tokenIsGood)
return false;
var success = false;
var response = new HttpResponseMessage();
try
{
response = await _client.GetAsync(Constants. MyObjectDisplayUrl);
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine("Error requesting updated list.");
System.Diagnostics.Debug.WriteLine(e.Message);
System.Diagnostics.Debug.WriteLine(e.StackTrace);
return success;
}
response.EnsureSuccessStatusCode();
success = true;
var responseBody = await response.Content.ReadAsStringAsync();
// Update list
MyObjects.Clear();
MyObjects = JsonConvert.DeserializeObject<ObservableCollection< MyObject >>(responseBody);
//Alert subscribed ViewModels to update list
MessagingCenter.Send<object, ObservableCollection< MyObject >>(Application.Current, Constants.ListUpdateContract, units);
return success;
}
由于maps.Pins
与UI相关,因此必须在主UI线程中运行。
[MessagingCenter
并不总是在主线程中发布/订阅。
因此,要解决此问题,请在主线程中调用maps.Pins.Clear()
。>
Device.BeginInvokeOnMainThread(()=> maps.Pins.Clear());
信用:@shanranm,用于提及使用主线程的
MessagingCenter
的局限性。