I have an application in production that contains an AppWidget that schedules periodic refreshes via a WorkManager CoroutineWorker. My RefreshWidgetWorker simply requests some data from a Retrofit service & then persists that data via a Room DAO. I am receiving hundreds of crash logs of network connectivity issues & reports from users that the widget will not load for them. The exception is typically:
java.net.UnknownHostException: Unable to resolve host "[my-server]": No address associated with hostname
Although I've also seen:
java.net.SocketTimeoutException: failed to connect to (port ###) from (port #####) after ####
The flow is as follows:
widget onUpdate() gets called (every hour) -> check X duration since last refresh -> schedule RefreshWidgetWorker -> request from remote api -> display widget view -> persist cached data
My AppWidgetProvider (paraphrasing) looks like the following:
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
GlobalScope.launch {
if (timeSinceLastRefresh >= refreshThreshold) {
val initialWorkRequest = OneTimeWorkRequest.Builder(RefreshWidgetWorker::class.java).setInputData(/*requestData*/).build()
WorkManager.getInstance(context).enqueueUniqueWork(
REFRESH_WIDGET_WORK_NAME, ExistingWorkPolicy.KEEP, initialWorkRequest
)
}
}
}
My RefreshWidgetWorker looks like:
class RefreshWidgetWorker(val context: Context, workerParams: WorkerParameters) :
CoroutineWorker(context, workerParams), KoinComponent {
private val dataService: DataService by inject()
override suspend fun doWork(): Result {
val d = dataService.getData()
val views = RemoteViews(context.packageName, R.layout.widget_layout).apply {
setTextViewText(R.id.textView, d.item)
}
AppWidgetManager.getInstance(context).updateAppWidget(widgetId, views)
cache.put(d)
return Result.success()
}
And DataService is just a simple Retrofit service:
Retrofit.Builder()
.baseUrl(Constants.API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()))
.client(
OkHttpClient.Builder().connectTimeout(2, TimeUnit.SECONDS)
.readTimeout(2, TimeUnit.SECONDS).writeTimeout(2, TimeUnit.SECONDS).build()
)
.build()
.create(DataService::class.java)
I've been unable to reproduce this issue on my own device & am unsure if it has to do with spotty mobile networks or a system optimization that is preventing my requests from going through. I'd appreciate any insight anyone might be able to provide as I have been stumped on this issue for a while.