Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Thread.start() CalledFromWrongThreadException

I am not sure if my understating is correct because I am not getting the expected output. I have a class within which I am calling a method that is supposed to start a thread.

public class MainActivity extends Activity {

protected void onCreate(Bundle savedInstanceState) {
beginListenForData()
}

The beginListenForData function is to start a thread and check at times if data is there for reading. If that's the case, it reads and updates a UI variable :

void beginListenForData()
{
    Thread workerThread = new Thread(new Runnable() {
        @Override
        public void run()
        {    
            int bytesAvailable = 3;
            while(!Thread.currentThread().isInterrupted())
            {
                try
                {
                    bytesAvailable = mmInStream.available();
                    if(bytesAvailable > 0)
                    {
                        byte[] packetBytes = new byte[bytesAvailable];
                        mmInStream.read(packetBytes);
                bytesAvailable = mmInStream.available();
                String s = new String(packetBytes);
                text.setText(s);
                    }
                }
                catch (Exception e)
                {
            // TODO Auto-generated catch block
                e.printStackTrace();
                }
            }
        }
    });

       workerThread.start();
   }

}

I am not getting the desired output. That thread should read the data or check if the data is available. If available then read it and set a UI variable to the values read.

Am I doing the implementation correctly? Do I have something wrong in my code?

like image 863
Programmer Avatar asked Mar 20 '23 01:03

Programmer


2 Answers

A normal Thread should not access the UI thread. I would advise using an AsyncTask instead of using standard Threads or Runnables in Android. An AsyncTask can be used to both simultaneously work away from the UI thread, and then make changes to it. Everything called in the doInBackground() method is done away from the main UI thread, and everything called in the onPreExecute() and onPostExecute() methods can interact nicely with your UI.

An AsyncTask is recommended when your calling a new thread from something running on the UI Thread (like an Activity, as in your instance). Example below;

public class YourAsyncTask extends AsyncTask{

    @Override
    protected Object doInBackground(Object... arg0) {
        // Work to be done in the background.
        return null;
    }

    @Override
    protected void onPostExecute(String result) {
        // Changes to be made to UI
    }

    @Override
    protected void onPreExecute() {
         // Changes to be made to UI
    }

}

Then you can just run the AysncTask from your activity like so;

new YourAsyncTask().execute("");

To work on your Activity, you may need to create a custom constructor for your AysncTask and pass your activity instance to it through the constructor, to be stored in an instance variable. I hope this helps.

Further Information;

  • When to use an AsyncTask vs Handler vs Thread
like image 84
Rudi Kershaw Avatar answered Apr 01 '23 14:04

Rudi Kershaw


Thread can't update GUI You can use runOnUiThread() method or use Handler

EDIT : example of Handler : How to use an Android Handler to update a TextView in the UI Thread?

like image 26
JossVAMOS Avatar answered Apr 01 '23 13:04

JossVAMOS