Natalie
Natalie

Reputation: 315

Android Studio Error: Can't create handler inside thread that has not called Looper.prepare()

I am trying to run a section of code every X seconds in an AsyncTask Activity and it is crashing before getting into any print statements. I am not sure why it is crashing, but I also posted the error I am getting. Anyone have any ideas? Thank you so much!

public class AppListener extends AsyncTask<String, String, String> {

@Override
protected String doInBackground(String... uri) {


    final Handler h = new Handler();
    final int delay = 5000; //milliseconds

    h.postDelayed(new Runnable() {
        public void run() {


            try {

                String msg_received = null;

                System.out.println("LISTENING FOR LAST INSTALLED APP");


                System.out.println("TRY");

                Socket socket = new Socket("85.190.178.23", 5050);

                // Get data sent through socket
                DataInputStream DIS = new DataInputStream(socket.getInputStream());

                System.out.println("DataInputStream Started");

                // read data that got sent
                msg_received = DIS.readUTF();

                System.out.println("Message from server" + msg_received);

                // Might not want to close socket, or only the first string will be sent and none after
                socket.close();


            }

            catch (Exception e) {
                System.out.println("Did not receive string");
            }




            h.postDelayed(this, delay);
        }
    }, delay);



    String msg_received = null;
    return msg_received;


}

}

MY ERROR

Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

Here is how I got my loop to execute every X seconds without interfering with my GUI if it is helpful to anyone else: instead of having a separate class, I just posted my code in my main activity right when my app starts

public class MainActivity extends FragmentActivity{



private Thread repeatTaskThread;


// called when the activity is first created
@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);


  // Go into loop that is repeated every X seconds
  RepeatTask();
}




private void RepeatTask()
{
  repeatTaskThread = new Thread()
  {
     public void run()
     {
        while (true)
        {

         //Post your code here that you want repeated every X seconds
         // My "try" and "catch" statements from above got inserted here


           try
           {
              // Sleep for 5 seconds
              Thread.sleep(5000);
           }
           catch (Exception e)
           {
              e.printStackTrace();
           }
        }
     };
  };
  repeatTaskThread.start();

}
}

Upvotes: 0

Views: 666

Answers (1)

Clark Wilson
Clark Wilson

Reputation: 389

Updated: When you're launching AsyncTasks doInBackground, you're launching a background thread. If you want to post AsyncTask's doInBackground with a delay, then you should not use an AsyncTask at all. You should only need to use a Handler with postDelayed, which will create a background thread for you. It looks like in your code, you tried launch a new Thread with a Handler while in AsyncTask's background thread.

Get rid of the AsyncTask altogether, and include this code in your Activity:

final Handler h = new Handler();
final int delay = 5000; //milliseconds

h.postDelayed(new Runnable() {
    public void run() {


        try {

            String msg_received = null;

            System.out.println("LISTENING FOR LAST INSTALLED APP");


            System.out.println("TRY");

            Socket socket = new Socket("85.190.178.23", 5050);

            // Get data sent through socket
            DataInputStream DIS = new DataInputStream(socket.getInputStream());

            System.out.println("DataInputStream Started");

            // read data that got sent
            msg_received = DIS.readUTF();

            System.out.println("Message from server" + msg_received);

            // Might not want to close socket, or only the first string will be sent and none after
            socket.close();


        }

        catch (Exception e) {
            System.out.println("Did not receive string");
        }




        h.postDelayed(this, delay);
    }
}, delay);



String msg_received = null;
return msg_received;


    }

Upvotes: 1

Related Questions