When using a background thread to do work, typically you'd update the UI through a Handler.
One way to do this was defining a handler at the class level as outlined in this answer, and this answer
final Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
//update UI or call class methods here
}
};
However, this construct would result in the following warning
Handler class should be static otherwise memory leaks might occur
Another way to do this was to use a static inner class as outlined in this answer, and this answer
static class MyHandler extends Handler {
private final WeakReference<Type> myWeakReference;
MyHandler(Type reference) {
myWeakReference = new WeakReference<Type>(reference);
}
@Override
public void handleMessage(Message msg)
{
//Update UI or call class methods here using weak reference
}
}
However, this form of constructor has been Deprecated according to the Android docs.
public Handler ()
This constructor is deprecated. 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, {link android.view.View#getHandler}, or similar. If the implicit thread local behavior is required for compatibility, use new Handler(Looper.myLooper()) to make it clear to readers.
How should updating the UI from a Handler be done currently, and should a Handler still be used for this purpose.
As you stated the docs, it says to use Looper.getMainLooper()
, just change your code to:
MyHandler(Type reference) {
super(Looper.getMainLooper());
myWeakReference = new WeakReference<Type>(reference);
}
to update the UI from the main/UI thread.