官术网_书友最值得收藏!

A synchronous function wrapped in an asynchronous caller

The first approach is quite simple. We can create a loadNews() function that directly invokes fetchRssHeadlines() and displays its results in the same way we did before:

private fun loadNews(){
val headlines = fetchRssHeadlines()
val newsCount = findViewById<TextView>(R.id.newsCount)
launch(UI) {
newsCount.text = "Found ${headlines.size} News"
}
}

Notice that this function is synchronous, and will call fetchRssHeadlines() in the same thread that it's called. Consider this code, for example:

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
loadNews()
}

Doing this will result in a NetworkOnMainThreadException being thrown. Since loadNews() uses the same thread it's being called on, the request to fetch the feed will happen in the UI thread. To fix this, we can then wrap the call to loadNews() in a launch() block like we did before, using the dispatcher that was created for the service request. The code would be almost the same:

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
launch (dispatcher) {
loadNews()
}
}

This code is quite explicit, indicating that there is some code being executed asynchronously, which is a great practice. It's also quite flexible, because if the caller of loadNews() is already in a background thread, it can fetch the news in the same background thread, without having to use a launch() or async() builder.

The disadvantage of this approach is that if we have many places calling loadNews() from the UI thread, we would have many similar blocks of launch(dispatcher) {...} spread in the code, which can make the code less readable.

主站蜘蛛池模板: 罗城| 林西县| 青海省| 清水河县| 黄山市| 龙游县| 两当县| 滁州市| 汾阳市| 平湖市| 饶平县| 淮滨县| 报价| 吴桥县| 丰镇市| 本溪市| 攀枝花市| 巢湖市| 平顺县| 平湖市| 陆良县| 丹江口市| 乐山市| 张北县| 龙口市| 华坪县| 东乌珠穆沁旗| 鄂托克旗| 建宁县| 吴川市| 青神县| 焉耆| 稻城县| 临猗县| 元氏县| 忻州市| 新平| 长岭县| 扬中市| 额尔古纳市| 上饶县|