小部件服务在尝试填充集合之前不会等待数据
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
看来我又卡住了。我的小部件工作了一半,我 想 我知道它失败的原因,但我不知道如何修复它。
在我的小部件服务 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