Search code examples
androidandroid-contextandroid-looper

What is the best practice to get Looper?


I have tried mContext.getMainLooper() and Looper.getMainLooper(). And both return the same result, but I would like to know which should be proper way?

I also read this from an Android developer link this and this:

For Looper.getMainLooper():

Looper getMainLooper () Returns the application's main looper, which lives in the main thread of the application.

For mContext.getMainLooper():

Looper getMainLooper () Return the Looper for the main thread of the current process. This is the thread used to dispatch calls to application components (activities, services, etc). By definition, this method returns the same result as would be obtained by calling Looper.getMainLooper().


Solution

  • getMainLooper() As a method, it will return the same result regarding the way you called it, so you can consider the two are the same, as returning the Looper from the context will get you the same result when returning the looper from the application, and to get it better look at the Looper class and see how it returns the looper:

    private static Looper sMainLooper;
    
    public static Looper getMainLooper() {
    
        synchronized (Looper.class) {
    
            return sMainLooper;
    
        }
    
    }
    
    public static void prepareMainLooper() {
    
        prepare(false);
    
        synchronized (Looper.class) {
    
            if (sMainLooper != null) {
    
                throw new IllegalStateException(
                        "The main Looper has already been prepared.");
    
            }
    
            sMainLooper = myLooper();
    
        }
    
    }
    
    public static Looper myLooper() {
    
        return sThreadLocal.get();
    
    }
    

    and when looking at the get() method in ThreadLocal.class:

    public T get() {
    
        Thread t = Thread.currentThread();
    
        ThreadLocalMap map = getMap(t);
    
        if (map != null) {
    
            ThreadLocalMap.Entry e = map.getEntry(this);
    
            if (e != null)
    
                return (T) e.value;
    
        }
    
        return setInitialValue();
    
    }
    

    and Thread.currentThread(); according to Thread.class docs:

    Returns: the currently executing thread.

    which is the thread that is holds the context in the case of running android.


    And after all, I see that what should bothers you is that not how to get the main looper but what is the best practice you should follow when dealing with loopers, like when to use getMainLooper() and when to use Looper.prepare(), as described here:

    Looper.prepareMainLooper() prepares looper in main UI thread. Android applications normally do not call this function. As main thread has its looper prepared long before first activity, service, provider or broadcast receiver is started.

    But Looper.prepare() prepares Looper in current thread. After this function is called, thread can call Looper.loop() to start processing messages with Handlers.

    And also you should know the difference between getMainLooper() and myLooper(), as described here:

    getMainLooper

    Returns the application's main looper, which lives in the main thread of the application.
    

    myLooper

    Return the Looper object associated with the current thread. Returns null if the calling thread is not associated with a Looper.