首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android :异步调用后如何更新recyclerView?获取CalledFromWrongThreadException

Android :异步调用后如何更新recyclerView?获取CalledFromWrongThreadException
EN

Stack Overflow用户
提问于 2019-02-09 20:03:22
回答 2查看 981关注 0票数 2

我正在尝试执行异步调用,然后更新一个RecyclerView。很像这个问题中概述的内容:RecyclerView element update + async network call

但是,当我尝试这样做时,我会得到以下错误:android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

下面是我的代码(主要问题在setAlbums函数中):

代码语言:javascript
复制
class AlbumActivity : AppCompatActivity() {

    protected lateinit var adapter: MyRecyclerViewAdapter
    protected lateinit var recyclerView: RecyclerView
    var animalNames = listOf("nothing")

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_album)

        recyclerView = findViewById<RecyclerView>(R.id.rvAnimals)
        recyclerView.layoutManager = LinearLayoutManager(this)
        adapter = MyRecyclerViewAdapter(this, animalNames)
        recyclerView.adapter = adapter

        urlCall("https://rss.itunes.apple.com/api/v1/us/apple-music/coming-soon/all/10/explicit.json")

    }

    private fun urlCall(url: String) {

        val client = OkHttpClient()
        val request = Request.Builder().url(url).build()

        client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {}
            override fun onResponse(call: Call, response: Response) = getJSON(response.body()?.string())
        })
    }

    fun getJSON(data: String?) {

        val gson = Gson()
        val allAlbums = ArrayList<Album>()

        val jsonResponse = JSONObject(data)
        val feed = jsonResponse.getJSONObject("feed")
        val albums = feed.getJSONArray("results")

        for (i in 0 until albums.length()) {
            val album = albums.getJSONObject(i)
            allAlbums.add(gson.fromJson(album.toString(), Album::class.java))
        }
        setAlbums(allAlbums)
    }


    fun setAlbums(albums: ArrayList<*>) {

        animalNames = listOf("sue", "betsie")
        adapter.notifyDataSetChanged() // This is where I am telling the adapter the data has changed
    }

    internal inner class Album {
        var artistName: String? = null
        var name: String? = null
    }
}

有人知道我的问题吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-02-09 20:14:25

您需要在主线程上执行您想要的代码,如下所示:

代码语言:javascript
复制
runOnUiThread(new Runnable() {

@Override
public void run() {
    //update your UI
    }
});
票数 3
EN

Stack Overflow用户

发布于 2019-02-09 20:17:01

您的Callback函数将在后台线程上调用。在某种程度上,这是因为OkHttp不是一个特定于Android的库,所以它不知道Android的主要应用程序线程。

您需要做一些事情来更新主应用程序线程中的UI。现代选择包括:

  • 让您的Callback更新一个UI观察到的MutableLiveData,然后UI将在主应用程序线程上获得更新
  • 使用现有的using OkHttp with RxJava菜谱
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54610219

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档