-1

From everything I read it should work, however the following:

runOnUiThread {
               recyclingView_Main.adapter = MainAdapter()
              }

inside

fun fetchJson(){

        println("attempting to fetch JSON")

        val url = "https://api.drn1.com.au/station/allstations"

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

        val client = OkHttpClient()
        client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                e.printStackTrace()
            }

            override fun onResponse(call: Call, response: Response) {
                response.use {
                    if (!response.isSuccessful) throw IOException("Unexpected code $response")

                    for ((name, value) in response.headers) {
                        println("$name: $value")
                    }

                    val body = response.body!!.string()
                    val gson = GsonBuilder().create()
                    val stationfeed = gson.fromJson(body, StationsFeed::class.java)



                    runOnUiThread {
                    recyclingView_Main.adapter = MainAdapter()
                    }
                    println(body)
                }
            }
        })
    }

Is not working. Like the app loads, but the recyclingView_Main.adapter = MainAdapter() seems to not run.

fullcode:

package com.example.drn1

import android.graphics.Color
import kotlinx.android.synthetic.main.activity_main.*
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import okhttp3.*
import java.io.IOException

class MainActivity : AppCompatActivity() {

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

        recyclingView_Main.layoutManager = LinearLayoutManager( this, LinearLayoutManager.HORIZONTAL, false)

       // recyclingView_Main.adapter = MainAdapter() --- THIS DOES WORK WHEN IT IS HERE

        fetchJson()
    }


    fun fetchJson(){

        println("attempting to fetch JSON")

        val url = "https://api.drn1.com.au/station/allstations"

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

        val client = OkHttpClient()
        client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                e.printStackTrace()
            }

            override fun onResponse(call: Call, response: Response) {
                response.use {
                    if (!response.isSuccessful) throw IOException("Unexpected code $response")

                    for ((name, value) in response.headers) {
                        println("$name: $value")
                    }

                    val body = response.body!!.string()
                    val gson = GsonBuilder().create()
                    val stationfeed = gson.fromJson(body, StationsFeed::class.java)



                    runOnUiThread {
                    recyclingView_Main.adapter = MainAdapter()
                    }
                    println(body)
                }
            }
        })
    }
}


class StationsFeed(val data: List<Data>)

class Data(val _id: String, val name: String, val imageurl: String)

As you can see from the code above when I put it in the onCreate it works fine.

So the issue seems to be sending it to the main thread.

XML

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclingView_Main"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginBottom="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.0" />
</androidx.constraintlayout.widget.ConstraintLayout>
RussellHarrower
  • 5,971
  • 17
  • 81
  • 163
  • Can you post your XML? – Sharan May 23 '21 at 05:15
  • the issue was I needed to wrap Thread around the runOnUiThread {} – RussellHarrower May 23 '21 at 05:17
  • I want to recreate your implementation in Android Studio. – Sharan May 23 '21 at 05:17
  • 1
    @Sharan I am a complete noob at Kotlin but I just been following the YouTube video - it's out dated a little like the short code he uses does not work. Due to Kotlin moving to Bindings - something I am still having to learn. – RussellHarrower May 23 '21 at 05:19
  • Don't worry we are anyway learning all the time. – Sharan May 23 '21 at 05:21
  • You do not need `runOnUiThread` here `Call#onResponse` already getting called on main Thread . Just try and print the thread name with `Thread.currentThread.name`. Also How r u passing data to `MainAdapter` u seems to be using default constructor and there is no set data call either ? – ADM May 23 '21 at 07:38
  • https://stackoverflow.com/questions/29141729/recyclerview-no-adapter-attached-skipping-layout#comment49234469_30581896 – Zoe May 23 '21 at 08:31

1 Answers1

0

The thing that solved it for me was

Thread {
    runOnUiThread {
        binding.recyclingViewMain.adapter = MainAdapter(stationfeed)
    }
}.start()

I forgot that you need to have Thread wrapped around runOnUiThread.

Anand
  • 300
  • 4
  • 10
RussellHarrower
  • 5,971
  • 17
  • 81
  • 163
  • Though this may have worked, I added a answer for you, such that you don't have to create a new `MainAdapter` instance every time there is a station feed – Sharan May 23 '21 at 05:48
  • 1
    This is completely wrong. Instead you should have used runOnUiTread(new Runnable(){run{//here your code}}); – blackapps May 23 '21 at 07:27