Search code examples
javaandroidmultithreadingbackground-processforeground-service

Code executed inside a foreground service: one into main thread and one into a different thread


I am basically trying to understand on which threads my code is running. In theory it should all run in the foreground group since the code is inside a Service started in the foreground. Let's say I have the following classes:

public class Test {

    private Runnable runnable;
    private final Handler handler;


    public Test()
    {
        this.random = new Random();
        this.handler = new Handler();
    }


    private Runnable getRunnable(final String gpsCoordinates)
    {
        return new Runnable() {
            @Override
            public void run() {
                System.out.println("Current Thread Test: "+Thread.currentThread().getName());
                System.out.println("Current Looper Test: "+ Looper.myLooper());
                handler.postDelayed(this, INTERVAL_MILLIS);
                if(condition)
                    handler.removeCallbacks(runnable);
            }
        };
    }

    public void test(final String gpsCoordinates)
    {
        runnable = getRunnable(gpsCoordinates);
        handler.postDelayed(runnable,  DELAY_MILLIS);
    }
}


public class FooThread extends Thread {

    private Test test;
    ...

    public FooThread(Test test)
    {
        this.test = test;
    }


    @Override
    public void run()
    {
            test.test();
            //other stuff
            System.out.println("Current Thread FooThread: "+Thread.currentThread().getName());
            System.out.println("Current Looper FooThread: "+ Looper.myLooper());
    }

}

As you can see I have a Test class that execute some code at some interval until a condition is met and a class FooThread which call Test.test other than doing other stuff.

Inside my service I simply run:

new FooThread(new Test()).start();

To my surprise this is what I get:

Current Thread FooThread: Thread-3
Current Looper FooThread: null

Current Thread Test: main
Current Looper Test: Looper (main, tid 2) {3c367e9}

Could someone explain to me why test.test() is on the main thread since the code it's inside a runnable? Also, I can check that Thread-3 is indeed a Thread in the foreground group and not in the background group? Generally, threads in the foreground group get about 95% of the total execution time from the device, while the background group gets roughly 5%. Thank you.


Solution

  • Could someone explain to me why test.test() is on the main thread since the code it's inside a runnable?

    Because that's where you initialized it.

    You said:

    > Inside my service I simply run:
    
    new FooThread(new Test()).start();
    
    

    So ...

    1. You're in a service, so you start on the main thread.
    2. You create a new Test(), which is created on the main thread.
    3. Test constructor creates new Handler(), which again is created on the main thread.
    4. You start() the Thread, which spawns Thread-3
    5. Thread-3 sends a delayed message to Handler() which will run on the main thread it was created on.
    6. The Thread runnable prints that it's on the Thread-3 thread that it spawned, as expected.
    7. Your delayed handler - which is running on the main thread - eventually prints that it's on the main thread, as expected.

    The fact that the handler is using a Runnable is irrelevant. A Runnable is just an interface for "something that can run" - it does not have to be a thread. A Thread is a Runnable - a Runnable is not a Thread.

    Also, I can check that Thread-3 is indeed a Thread in the foreground group and not in the background group?

    Is that a question or comment? Yes, you can get a Thread priority.

    EDIT: move new Test() to inside the Thread run method to see the difference.