0

I am getting a

kotlin.UninitializedPropertyAccessException: lateinit property BTNStatus05 has not been initialized

When I try to set a ButtonColor. The idea is to change butttoncolor etc on a button, based on reply via a TCPsocket. In my

My Main Activity Simplified:

class MainActivity() : AppCompatActivity(), Parcelable {
    constructor(parcel: Parcel) : this() {

    }
    private var fgm: SygicNaviFragment? = null
    private var uiInitialized = false
    private val TAG = "MainActivity"
    private lateinit var socketHandler: SocketHandler
    private lateinit var handlerThread: HandlerThread
    lateinit var BTNStatus05 : Button


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (PermissionsUtils.requestStartupPermissions(this) == PackageManager.PERMISSION_GRANTED) {
            checkSygicResources()
            Log.i(TAG, "onCreate: Sygic Resources checked")
        }
        //this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN)

        window.decorView.apply {
           systemUiVisibility = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_FULLSCREEN
        }
        setContentView(R.layout.activity_main)

        handlerThread = HandlerThread("").apply {
            start()
            socketHandler = SocketHandler(looper)


            socketHandler?.obtainMessage()?.also { msg ->
                msg.what = 0
                msg.obj = "INIT"
                msg.arg1 = 0
                socketHandler?.sendMessage(msg)}

        }
       
        // set on-click listener
        BTNStatus05= findViewById(R.id.statusbutton05) as Button
        Log.d(TAG, "BTN05" + BTNStatus05)
            //BTNStatus05.setBackgroundColor(Color.YELLOW)
            //BTNStatus05.setEnabled(false)
        BTNStatus05.setOnClickListener {
            socketHandler?.obtainMessage()?.also { msg ->
                msg.what = 1
                msg.obj = "btnpress"
                msg.arg1 = 5
                socketHandler?.sendMessage(msg)
            }
            Toast.makeText(this@MainActivity, "Status05 Clicked.", Toast.LENGTH_SHORT).show()
        }
            
    fun Test() {
           Log.d(TAG, "DATA on Mainthread? " + Thread.currentThread().name)
           Log.d(TAG, "Stop: We Got a button:")
           BTNStatus05.setBackgroundColor(Color.YELLOW)
           BTNStatus05.setEnabled(false)
    }

    override fun onCreateDialog(id: Int): Dialog {
        return fgm?.onCreateDialog(id) ?: return super.onCreateDialog(id)
    }

    override fun onPrepareDialog(id: Int, dialog: Dialog) {
        super.onPrepareDialog(id, dialog)
        fgm?.onPrepareDialog(id, dialog)
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        fgm!!.onNewIntent(intent)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        fgm?.onActivityResult(requestCode, resultCode, data)
    }

    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
        return fgm?.onKeyDown(keyCode, event) ?: return super.onKeyDown(keyCode, event)
    }

    override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean {
        return fgm?.onKeyUp(keyCode, event) ?: return super.onKeyUp(keyCode, event)
    }



    override fun writeToParcel(parcel: Parcel, flags: Int) {

    }


       override fun describeContents(): Int {
        return 0
    }

    companion object CREATOR : Parcelable.Creator<MainActivity> {
        override fun createFromParcel(parcel: Parcel): MainActivity {
            return MainActivity(parcel)
        }

        override fun newArray(size: Int): Array<MainActivity?> {
            return arrayOfNulls(size)
        }
    }


   inner class MainHandler(mainlooper: Looper) : Handler(mainlooper) {
        private val TAG = "MainActivity"
        val mainA = MainActivity()
       val mapper = jacksonObjectMapper()
        override fun handleMessage(msg: Message) {
            Log.d(TAG, "Handle")
            super.handleMessage(msg)
            val jsonstr = msg?.obj as String
            val jsontree = mapper.readTree(jsonstr)
            val type = jsontree.get("type").asText()
            Log.d(TAG, "Mainhandler: jsonstr - " + jsonstr)
            Log.d(TAG, "MainHandler:Json type -  " + type )
            when(type) {
                           "button" -> {
                    Log.d(TAG, "We got button update: " + type)

                        MainActivity().runOnUiThread(Runnable {
                        BTNStatus05.setBackgroundColor(Color.YELLOW) })
                        //BTNStatus05.setBackgroundColor(Color.YELLOW)

                }
                else -> Log.d(TAG, "unknown what " + type)
            }
                   }
    }
}

I tried:

when(type) {
                           "button" -> {
                    Log.d(TAG, "We got button update: " + type)

                        MainActivity().runOnUiThread(Runnable {
                        BTNStatus05.setBackgroundColor(Color.YELLOW) })
                        //BTNStatus05.setBackgroundColor(Color.YELLOW)

                }
                else -> Log.d(TAG, "unknown what " + type)


And also just did a call to test() instead... Any ideas?

  • You must never instantiate an Activity class. It will be an invalid instance, and it doesn’t make any sense to do this. – Tenfour04 Jul 22 '23 at 04:01
  • Hi. Ok. So what is the correct way? All i need i just to interact wirh the buttons. – Jesper Blom Jul 22 '23 at 12:15
  • Just delete the `MainActivity().` from that code before the `runOnUiThread` call, and delete the `val mainA` line. You are already inside your activity class since your handler is an inner class of your activity. But you should look into coroutines. This code is exceeding complicated for no justified reason I can see. Messing with handlers and messages is pretty low level stuff. Nowadays, we have coroutines and Executors so you shouldn’t have to touch that stuff unless you’re doing something very complicated that has to be done in Java so it can be in a shared library. – Tenfour04 Jul 22 '23 at 12:53
  • Hi. Tried to delete what you said, and is down to: "button" -> { Log.d(TAG, "We got button update: " + type) runOnUiThread(Runnable { BTNStatus05.setBackgroundColor(Color.YELLOW) }) However still get the same exception? – Jesper Blom Jul 22 '23 at 19:09
  • Oh, the other problem is that you are starting your HandlerThread before that property is initialized, so there is a race condition where it might be accessed before it is initialized. – Tenfour04 Jul 22 '23 at 19:40
  • Hi my HandlerThread is for the SocketClient Class for messages From MainActivity. The MainLooper is "build in" and handled by the Constructor... But might be an issue too.. – Jesper Blom Jul 22 '23 at 20:09
  • I don't see where you're doing anything in your constructor. When you are doing things with an Activity, you need to work with its lifecycle methods. If you start a thread that starts touching your properties before `onCreate()`, you will have problems with anything that is `lateinit` or dependent on the `Context` of the Activity. I also see you're trying to make the activity class a Parcelable which doesn't make sense, because you can never instantiate your own Activities. – Tenfour04 Jul 22 '23 at 21:55
  • Hi. Sorry I am new to UI and activities ;) Has always just made the stuff for sockets ect.. Can you guide me a little bit more. How should it then be done. I just thought that an innerclass would hanlde all the context. Would it be a better idea using LiveData for updating all the UI part? – Jesper Blom Jul 23 '23 at 08:19

0 Answers0