Search code examples
androidmultithreadingthread-safetyjava-threadsandroid-looper

loopers in java vs thread without looper, and correct way to stop looper?


My question is in regards to java loopers and also how to stop them the correct way.

Lets say i have a thread defined something like this:

    class NoLooperThread extends Thread{
        @Override
        public void run(){

            Thread.sleep(2000);

        }
}

and i have another thread almost the same but with a looper:

class LooperThread extends Thread{

    @Override
    public void run(){
        Looper.prepare();

        Thread.sleep(2000);

        Looper.loop();
    }
}

Now if i do : new NoLooperThread().start(); i want to know after 2 seconds this thread will potentially die but if i do: new LooperThread().start(); the thread continues to block forever ? is my assumption correct ?

and how would i stop this thread ? i know i need call Looper.myLooper().quit(); to stop the blocking but whats the best way to do it ? should i send a message through a handler to stop it ?

so then the purpose of Looper is two fold: it creates a message queue but also keeps a thread alive, is that assumption also correct ?

My questions come after reading SO question here


Solution

  • After doing my own trial and error and research i thought i would share what i learned on loopers. In android the main thread already has a looper prepared. So we can make a handler to listen for messages right on the main thread and we never have to worry about loopers. But if we make another thread outside of main thread like this as an example:

          class LooperThread extends Thread{
    int count=0;
            int border=100;
            @Override
            public void run(){
               Looper.prepare();
    
                looperHandler = new Handler() {
                    @Override
                    public void handleMessage(Message msg) {
                        Log.i("HANDLER", "MyLooperThread called");
                        Bundle data = msg.getData();
                        if (data != null) {
                            count++;
                            if (count >= border) {
                                mainHandler.sendEmptyMessage(count);
                                count = 0;
                            }
                        }
                    }
                };
    
               Looper.loop();
            }
        }
    LooperThread.start();
    

    , then we MUST prepare a looper or else the handler cant run and cant handle messages. The handler needs a looper ! So that was my confusion as to why Looper.prepare() wasn't called on android main thread when using handler but in actuality it is being called for us.

    A Looper is intended for passing messages amongst threads. You would never use it in a asychTask as its already taken care of for you by android. Thats why in a asynchTask onPreExecute (UI thread) -sends messages to doInBackground (background thread) - which then sends messages to onPostExecute (UI thread again). Its using looper for message passing with handlers.

    As for quitting a Looper i don't think i would ever want to, i'd leave the thread running because its a type of messaging thread i've created usually by preparing a looper. I want to be actively queueing messages throughout the apps lifetime. I'll let it quit on its own when the app dies is my opinion.