Problems with Thread (Koltin)

Asked

Viewed 51 times

0

I am in a situation where I am building an APP for android to be consulting the Bitcoin price variations on the website Mercado Bitcoin.

The APP is already working, the last thing I want to implement is automatic consultation in time intervals.

The startAll() method triggers the query, plays the current data on the screen and stores some data in the database.

For this I am using a Thread, but when I call the startAll() method inside the Thread the APP closes. I don’t understand why, because this same scheme I can successfully reproduce in Intellij.

I even tried to put the method call inside a Try/catch to visualize the possible error, but without success.

NOTE: I put this class inside the onCreate

There’s another more appropriate way to do this?

Follows the code:

class thread() : Thread() {

        override fun run() {

            var count = 0
            while (count < 28000) {
                try{
                    startAll()
                }catch (ex:Exception){
                    errorMessage(ex.message.toString())
                }

                count++
                Thread.sleep(30000)

            }
        }
    }

    val t = thread()
    t.start()

The following error appears in LOG

07-18 08:47:31.234 1918-1956/com.example.tjsid.cry E/AndroidRuntime: FATAL EXCEPTION: Thread-172
Process: com.example.tjsid.cry, PID: 1918
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
    at android.os.Handler.<init>(Handler.java:200)
    at android.os.Handler.<init>(Handler.java:114)
    at android.widget.Toast$TN.<init>(Toast.java:345)
    at android.widget.Toast.<init>(Toast.java:101)
    at android.widget.Toast.makeText(Toast.java:259)
    at com.example.tjsid.cry.MainActivity.errorMessage(MainActivity.kt:103)
    at com.example.tjsid.cry.MainActivity$onCreate$thread.run(MainActivity.kt:70)
07-18 08:47:31.238 579-987/system_process W/ActivityManager:   Force finishing activity com.example.tjsid.cry/.MainActivity
07-18 08:47:31.296 592-592/? E/EGL_emulation: tid 592: eglCreateSyncKHR(1215): error 0x3004 (EGL_BAD_ATTRIBUTE)
07-18 08:47:31.386 1918-1934/com.example.tjsid.cry E/Surface: getSlotFromBufferLocked: unknown buffer: 0xdf9b44d0

Implementation of startAll()

fun startAll() {
    val basicUrl = "https://www.mercadobitcoin.net/api/"
    val urlBit = "BTC/ticker/"
    val urlLit = "LTC/ticker/"
    val urlBCash = "BCH/ticker/"
    val listViewBit = findViewById<ListView>(R.id.listaBit)
    val listViewLit = findViewById<ListView>(R.id.listaLit)
    val listViewBCash = findViewById<ListView>(R.id.listaBCash)
    val listViewDates = findViewById<ListView>(R.id.listaDate)
    get(basicUrl + urlBit)
    get(basicUrl + urlLit)
    get(basicUrl + urlBCash)
    down_bar.text = "Última atualização " + date.getAllHour()
    listViewBit.adapter = MyCustomAdapter(this, getLastPrice(urlBit, this), "bitcoin")
    listViewLit.adapter = MyCustomAdapter(this, getLastPrice(urlLit, this), "litcoin")
    listViewBCash.adapter = MyCustomAdapter(this, getLastPrice(urlBCash, this), "bcash")
    listViewDates.adapter = MyCustomAdapter(this, getLastDate(this), "date")
}
  • See if an error appears in the logcat. Also add in the question the implementation of the method startAll to facilitate.

  • I changed the post as suggested to help find the problem. This startAll() method is called as soon as the APP starts and is also linked to the button click event to update manually and this way it works, but I want the APP to do this update automatically while it is running in 30 seconds intervals, then I found this problem...

1 answer

1

The problem is that you are trying to change the view from another thread that is not the main.

Run the code changes the view in a block runOnUiThread:

runOnUiThread {
    down_bar.text = "Última atualização " + date.getAllHour()
    listViewBit.adapter = MyCustomAdapter(this, getLastPrice(urlBit, this), "bitcoin")
    listViewLit.adapter = MyCustomAdapter(this, getLastPrice(urlLit, this), "litcoin")
    listViewBCash.adapter = MyCustomAdapter(this, getLastPrice(urlBCash, this), "bcash")
    listViewDates.adapter = MyCustomAdapter(this, getLastDate(this), "date")
}

It seems your method errorMessage shows a Toast, then he would need this treatment:

runOnUiThread {
    errorMessage(ex.message.toString())
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.