33

I have a simple thread that goes like this:

public class AwesomeRunnable extends Thread {

    Handler thisHandler = null;
    Handler uihandler = null;
    String update = null;
    long time = 0;

    public AwesomeRunnable(Handler h, long howLong) {
        uihandler = h;
        time = howLong;
    }

    public void run() {
        Looper.prepare();
        thisHandler = new Handler();
  ...

EDIT: ADDED CODE THAT STARTS THE RUNNABLE

public class StartCycle implements Runnable {

    @Override
    public void run() {

        pomodoroLeft = numPomodoro;
        while(pomodoroLeft > 0) {
            pomodoroLeft--;
            actualSeconds = 6 * ONE_SECOND;
            runnable = new AwesomeRunnable(myHandler, actualSeconds);
            runnable.start();
            waitForClock();

It is an inner class of a main activity. This thread, however runs not on the main activity, but inside of another thread that runs on the main activity.

Anyway, this example is exactly the same as here, but for some reason it gives me java.lang.RuntimeException: Only one Looper may be created per thread.

I did not create any other loopers, at least explicitly anywhere.

user3081519
  • 2,659
  • 5
  • 25
  • 35
  • 1
    Can you show the code that starts the `AwesomeRunnable`? – fadden Apr 13 '14 at 03:33
  • That looks fine. Which line is throwing the exception? Which thread? (If you're looking at the logcat output in a terminal window, use `adb logcat -v threadtime` to show the thread ID on each line.) Something must be creating a looper twice in a single thread, so you need to figure out if it's running in the wrong thread, or something running twice in the new thread. – fadden Apr 13 '14 at 03:47
  • @fadden `Looper.prepare();` is throwing the exception. Ok...will try to go through log output as you suggested. – user3081519 Apr 13 '14 at 03:51
  • @fadden Actually the first line of the error message is: FATAL EXCEPTION: main. Does it mean it somehow creates another looper on the main thread? But why? – user3081519 Apr 13 '14 at 03:58
  • Sounds like it's trying to. If the two numbers (pid and tid) are the same, then it's definitely trying to create a new Looper in the main thread. Check the stack trace and see what's calling the function. – fadden Apr 13 '14 at 05:01

2 Answers2

97

java.lang.RuntimeException: Only one Looper may be created per thread

The exception is thrown because you (or core Android code) has already called Looper.prepare() for the current executing thread.

The following checks whether a Looper already exists for the current thread, if not, it creates one, thereby avoiding the RuntimeException.

    public void run() 
    {
            if (Looper.myLooper() == null)
            {
              Looper.prepare();
            }
            thisHandler = new Handler();

         ....
    }
Elad Nava
  • 7,746
  • 2
  • 41
  • 61
Aown Raza
  • 2,023
  • 13
  • 29
7

Instead of just calling Looper.prepare();, first check if Looper does not already exist for your Thread, if not, call that function. Like this:

if (Looper.myLooper()==null)
    Looper.prepare();
XPscode
  • 87
  • 1
  • 4