![](/img/trans.png)
[英]Is it safe to rely on the call to onDataSetChanged() after onCreated() in RemoteViewsFactory of an AppWidget
[英]Is it safe to use Coroutines runBlocking() inside onDataSetChanged of RemoteViewsFactory?
我正在嘗試獲取一些最新的電影圖像並將它們顯示在 Android 應用程序小部件中,根據要求,小部件應每小時刷新一次以獲取最新的電影圖像。
由於我在整個應用程序中使用協程,我需要使用現有的 retrofit 服務和暫停 function 來獲取數據。
根據 Android 文檔,在 RemoteViewsFactory 的 onDataSetChanged 內執行繁重的操作是安全的,因此我使用此方法本身從服務而不是 WorkManger 獲取數據,因為它有其自身的缺點。 見這里( https://commonsware.com/blog/2018/11/24/workmanager-app-widgets-side-effects.html )
在遠程適配器上觸發 notifyDataSetChanged() 時調用。 這允許 RemoteViewsFactory 通過更新任何內部引用來響應數據更改。 注意:在此方法中可以安全地同步執行昂貴的任務。 在此期間,舊數據將顯示在小部件中。
在下面的代碼片段中,我使用 runBlocking() 進行阻塞 retrofit 調用...否則將在獲取數據之前觸發獲取視圖。 這安全嗎?
注意:每隔一小時在 MyWidgetProvider 的 onUpdate 方法中也會注意到適配器
override fun onUpdate(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetIds: IntArray
) {
....
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.listViewMovies)
.....
}
代碼示例:MyRemoteViewsFactory:RemoteViewsFactory {
override fun onDataSetChanged() {
try {
fetchFromServer()
} catch (e: Exception) {
clear()
}
}
private fun refreshData() = runBlocking {
job = launch {
service.getMovieList?.also {
data = it
}
}
}
private fun clear(){
job?.cancel()
job = null
data = null
log("Cleared")
}
override fun onDestroy() {
clear()
}
所以我的查詢:
注意:這個問題專門針對 Android App Widget RemoteViewsFactory onDataSetChanged() 實現。
使用viewModel/lifeCycle
范圍, runBlocking
將阻塞 UI 線程。
1- 在 onDataSetChanged 方法中使用 runBlocking 是否安全?
3- 從 onDataSetChanged() 內部的網絡獲取數據是否安全。
該文檔特別指出“可以在此方法中安全地同步執行昂貴的任務。在此期間,舊數據將顯示在小部件中。”
所以問題 1 和 3 的答案是肯定的,在那里使用runBlocking
並進行網絡調用是可以的。
2- 在 runBlocking 中創建嵌套協程以取消協程是否安全? 有沒有更好的方法?
這樣做可能沒有真正的理由,因為runBlocking
阻塞線程,直到子協程完成,所以在工作完成之前你不會將控制權交還給調用者。 看下一個問題。
4-我無法在 onDataSetChanged() 中進行異步調用。所以無論如何我們可以在不使用 runBlocking() 的情況下進行處理
如果您想啟動以后可以取消的協程(如果同時使用onDataSetChanged
和clear
- 這還有待確認),您應該聲明一個CoroutineScope
(作為您的類的屬性)並使用該 scope 啟動協程而不是使用runBlocking
,然后在適當的時候/在適當的時候取消 scope。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.