小部件服务在尝试填充集合之前不会等待数据

Widget service doesn’t wait for data before trying to populate collection

看来我又卡住了。我的小部件工作了一半,我 我知道它失败的原因,但我不知道如何修复它。

在我的小部件服务 class 中,我在 onDataSetChanged() 方法中调用以获取我的数据(异步)。但是系统在加载数据之前调用了 getCount(),因此 returns 大小为 0,从不调用 getViewAt()。

如果我在 onDataSetChanged() 中创建一些假数据而不是调用从 Firebase 获取真实数据,那么它将正常显示。所以我知道它与此不同。

我尝试了各种方法来让它工作,但没有成功。我不想把它变成一个很长的问题,所以我会尽量保持简单。 我的问题是系统如何知道数据何时准备好? 似乎没有我可以调用的方法来通知它数据现在已经存在。

我可能完全错了,但我认为这就是问题所在。 onDataSetChanged() 方法不等待,我无法告诉它。

更令人困惑的是,在我使用假静态数据的应用程序的 mockDebug 版本中,它实际上可以工作,即使是异步调用也是如此。我的结论是它必须加载得如此之快,以至于在调用 getCount() 时它已经准备就绪。但更令人困惑的是,有一段时间它也在 prodDebug 版本中工作,然后就没有了,从那以后也没有。据我所知,那段时间我没有改变任何东西。无论如何,这是我能想到的唯一解释。原因是因为我可以通过调试器或日志记录看到当我从 Firebase 获取数据时在加载数据之前调用了 getCount() ,导致它失败,但如果我使用静态数据则在加载数据之后调用它, 让它成功。

如何让它等待?还是我可能做错了什么?

谢谢。

好的,所以我承认我不能异步执行此操作,并将 ItemWidgetProvider.onUpdate() 方法中的代码移至新的 IntentService。我将代码替换为使用 appWidgetIds 作为 Intent extra 启动服务的调用。

在这个新的 IntentService 中,我首先检索所有数据,然后调用之前从 onUpdate() 调用的代码。


我在使用此解决方案时遇到了一个问题,无论出于何种原因(如果您知道请发表评论),当我尝试将可序列化对象从 IntentService 传递到WidgetListService 它只是行不通。我创建了一个仅包含字符串的测试序列化对象,但即使这样也不起作用。与 Parcelable 相同。 为了解决这个问题,我将其转换为字节 [] 并改为发送 。这样可行。这是我唯一一次遇到这个问题,我使用 Serializable 将同一个对象保存到 onSaveInstanceState 并且它工作正常。不知道为什么只有小部件有问题。

编辑: 这不起作用。我可以在那里获取数据,但似乎没有办法更新小部件,所以它只适用于静态小部件。

好的,解决方案 2:使用 CountDownLatch.

将异步调用转换为同步调用

有了这个,我可以从 onDataSetChanged() 内部获取所有数据,就像我最初尝试的那样,只需要几行额外的代码。

到目前为止,我已经能够填充小部件列表并向其中添加数据。

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/CountDownLatch.html

Sync version of async method