Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Do We Get a Looper from an Executor?

Tags:

android

Google's documentation on bound services is promoting using a Messenger in lieu of your own custom binding for IPC. So, I am giving that a try for a particular experiment that I am running.

However, a Messenger needs a Handler. Nowadays, a Handler needs a Looper, and I might want one in this scenario for a background thread anyway (as opposed to Looper.getMainLooper()). The only other Looper that I know how to get is to run() a HandlerThread and get a Looper from it.

The documentation for the deprecated non-Looper forms of the Handler constructor have:

Implicitly choosing a Looper during Handler construction can lead to bugs where operations are silently lost (if the Handler is not expecting new tasks and quits), crashes (if a handler is sometimes created on a thread without a Looper active), or race conditions, where the thread a handler is associated with is not what the author anticipated. Instead, use an Executor or specify the Looper explicitly, using Looper#getMainLooper, View#getHandler, or similar.

(emphasis added)

Is this just strangely-worded documentation, or if there is a recipe for getting a Looper or Handler tied to an Executor that I cannot seem to find?

like image 684
CommonsWare Avatar asked Mar 25 '20 23:03

CommonsWare


People also ask

What is the use of Looper?

Looper is a class which is used to execute the Messages(Runnables) in a queue. Normal threads have no such queue, e.g. simple thread does not have any queue. It executes once and after method execution finishes, the thread will not run another Message(Runnable).

What is looper prepare?

↳ android.os.Looper. Class used to run a message loop for a thread. Threads by default do not have a message loop associated with them; to create one, call prepare() in the thread that is to run the loop, and then loop() to have it process messages until the loop is stopped.

Where will your build artifact go once Looper is done building your application?

All of the artifacts involved in the build process are typically retained in the repository.

How many loopers and handlers can be attached to a thread?

Each thread can have only one Looper. This is controlled by the ThreadLocal<Looper> object inside Looper class. So calling prepare method twice inside same thread will also lead to an exception.


1 Answers

I think they mean to suggest to use an Executor instead of a Handler. I don't know of any Executor implementation backed by a Looper.

Instead [of a Handler], use an Executor or specify the Looper explicitly, using Looper#getMainLooper, View#getHandler, or similar.

This is useful when you only need to run a Runable. For example the CameraManager.openCamera() method got an overload with the API level 28.

The behavior of this method matches that of openCamera(java.lang.String, StateCallback, android.os.Handler), except that it uses Executor as an argument instead of Handler.

If you require a Messenger, you'll always have to provide a Hanlder backed by a Looper, which was resolved by Looper.getMainLooper(), Looper.myLooper() or from a HandlerThread.

Alternatively you could create a Looper and run loop() on it. But this is basically what a HandlerThread does.

like image 77
tynn Avatar answered Sep 26 '22 12:09

tynn