我正在開發的應用程序顯示本地電車的時間表。數據從網站獲取,應該每30秒刷新一次。爲了在後臺執行提取操作,我以更適合scala的方式重新實現了AsyncTask。從class RichFuture[T](future: Future[U])
其經由隱式轉換富集Future
從定時器異步執行任務凍結用戶界面,當從後臺恢復
摘錄:
def mapUI[U](func: (T) ⇒ U)(implicit activity: Activity, ec: ExecutionContext): Future[U] = {
val promise = Promise[U]
future andThen {
case Success(value) ⇒
activity.runOnUiThread(new Runnable {
override def run(): Unit = {
try {
promise.success(func(value))
} catch {
case t: Throwable ⇒ promise.failure(t)
}
}
})
case Failure(fail) ⇒
promise.failure(fail)
}
promise.future
}
這實質上取代的AsyncTask which does not work in scala。全班可以在github看到。但我認爲這不是相關的。
的取功能的功能如下:
def fetchSchedule(): Unit = {
implicit val ec: ExecutionContext = ExecutionContext.fromExecutor(AsyncTask.THREAD_POOL_EXECUTOR)
Schedule.fetch(station) mapUI { schedules ⇒
Log.w("Jenastop", "Schedules are fetched")
/* Display results in UI */
} recoverUI {
case t: Throwable ⇒
/* Display error in UI */
}
}
其中fetchSchedule叫這個地方是這樣的:
protected override def onResume(): Unit = {
super.onResume()
Log.w("Jenastop", "Resume started")
// Setup timer that refreshes the data every 30
// seconds.
timer = new Timer
timer.scheduleAtFixedRate(new TimerTask {
override def run(): Unit = fetchSchedule()
}, 0, 30000)
Log.w("Jenastop", "Resume finished")
}
現在的問題:每當我把活動的背景和嘗試恢復它,它凍結,直到取得時間表。當我第一次啓動活動時,這種情況不會發生,但只有當我嘗試從後臺恢復時纔會發生。從背景中恢復時
日誌輸出是這樣的:
01-06 11:19:06.694 5280 5280 W Jenastop: Resume started
01-06 11:19:06.694 5280 5280 W Jenastop: Resume finished
01-06 11:19:07.974 5280 5280 I Choreographer: Skipped 71 frames! The application may be doing too much work on its main thread.
01-06 11:19:07.974 5280 5280 W Jenastop: Schedules are fetched
/* UI unfreezes */
不知何故,UI似乎要禁止,直到THREAD_POOL_EXECUTOR的任務就完成了。我怎樣才能繞過這個?
一個小細節。而不是'try {promise.successful(...)} catch ...}',你應該簡單地運行'promise.complete(Try(func(value)))'。 –
不是Android專家。所以'Schedule.fetch'運行一個未來,對吧?是否有一個原因,你必須使用'AsyncTask.THREAD_POOL_EXECUTOR'?根據我的經驗,您可以通過自定義池輕鬆阻止期貨。如果您使用默認執行上下文,則可以在將來需要避免此類情況的機構中使用'blocking {}'。 –
因爲您在'Schedule.fetch'內使用的Jsoup可能是阻塞的。使用異步http庫可能會更好。再一次,我在這裏幾乎沒有想法,但也許[這個博客](http://blog.ashwanik.in/2015/04/html-parsing-using-jsoup-and-volley-in-android.html)有助於做所以。 –