What do I use now that Handler() is deprecated?
Only the parameterless constructor is deprecated, it is now preferred that you specify the Looper
in the constructor via the Looper.getMainLooper()
method.
Use it for Java
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
// Your Code
}
}, 3000);
Use it for Kotlin
Handler(Looper.getMainLooper()).postDelayed({
// Your Code
}, 3000)
How to handle deprecated Handler in android
As mentioned by Mike in the comments, Handler
is not deprecated. The way of creating an object of Handler using new Handler()
is deprecated.
As per the documentation, using new Handler()
can lead to bugs. So you should specify a looper for the handler explicitly. Looper must not be null.
Refer the code:
private final Handler mHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_STATE_CHANGE:
break;
}
}
Handler().postDelayed is now deprecated. What function to call instead?
You need to use the constructor with an explicit looper, for the Main thread Looper use Looper.getMainLooper()
Handler(Looper.getMainLooper()).postDelayed({
notifyDataSetChanged()
}, 100)
Handler(Handler.Callback) is deprecated
From API level 30, there are 2 constructors are deprecated.
Handler()
Handler(Handler.Callback)
Google explains the reason below.
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(), callback) to make it clear to readers.
Solution 1: Use an Executor
1. Execute code in the main thread.
// Create an executor that executes tasks in the main thread.
Executor mainExecutor = ContextCompat.getMainExecutor(this);
// Execute a task in the main thread
mainExecutor.execute(new Runnable() {
@Override
public void run() {
// You code logic goes here.
}
});
2. Execute code in a background thread
// Create an executor that executes tasks in a background thread.
ScheduledExecutorService backgroundExecutor = Executors.newSingleThreadScheduledExecutor();
// Execute a task in the background thread.
backgroundExecutor.execute(new Runnable() {
@Override
public void run() {
// Your code logic goes here.
}
});
// Execute a task in the background thread after 1 second.
backgroundExecutor.schedule(new Runnable() {
@Override
public void run() {
// Your code logic goes here
}
}, 1, TimeUnit.SECONDS);
Note: Remember to shut down the executor after using.
backgroundExecutor.shutdown(); // or backgroundExecutor.shutdownNow();
3. Execute code in a background thread and update UI on the main thread.
// Create an executor that executes tasks in the main thread.
Executor mainExecutor = ContextCompat.getMainExecutor(this);
// Create an executor that executes tasks in a background thread.
ScheduledExecutorService backgroundExecutor = Executors.newSingleThreadScheduledExecutor();
// Execute a task in the background thread.
backgroundExecutor.execute(new Runnable() {
@Override
public void run() {
// Your code logic goes here.
// Update UI on the main thread
mainExecutor.execute(new Runnable() {
@Override
public void run() {
// You code logic goes here.
}
});
}
});
Solution 2: Specify a Looper explicitly by using one of the following constructors.
Handler(Looper)
Handler(Looper, Handler.Callback)
1. Execute code in the main thread
1.1. Handler with a Looper
Handler mainHandler = new Handler(Looper.getMainLooper());
1.2 Handler with a Looper and a Handler.Callback
Handler mainHandler = new Handler(Looper.getMainLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message message) {
// Your code logic goes here.
return true;
}
});
2. Execute code in a background thread
2.1. Handler with a Looper
// Create a background thread that has a Looper
HandlerThread handlerThread = new HandlerThread("HandlerThread");
handlerThread.start();
// Create a handler to execute tasks in the background thread.
Handler backgroundHandler = new Handler(handlerThread.getLooper());
2.2. Handler with a Looper and a Handler.Callback
// Create a background thread that has a Looper
HandlerThread handlerThread = new HandlerThread("HandlerThread");
handlerThread.start();
// Create a handler to execute taks in the background thread.
Handler backgroundHandler = new Handler(handlerThread.getLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message message) {
// Your code logic goes here.
return true;
}
});
Note: Remember to release the thread after using.
handlerThread.quit(); // or handlerThread.quitSafely();
3. Execute code in a background thread and update UI on the main thread.
// Create a handler to execute code in the main thread
Handler mainHandler = new Handler(Looper.getMainLooper());
// Create a background thread that has a Looper
HandlerThread handlerThread = new HandlerThread("HandlerThread");
handlerThread.start();
// Create a handler to execute in the background thread
Handler backgroundHandler = new Handler(handlerThread.getLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message message) {
// Your code logic goes here.
// Update UI on the main thread.
mainHandler.post(new Runnable() {
@Override
public void run() {
}
});
return true;
}
});
Handler() is deprecated
You can use LifecycleScope
for this to run every second:
lifecycleScope.launch {
while (true) {
delay(1000)
updateSeekBar()
}
}
What do I use now that BluetoothAdapter.getDefaultAdapter() is deprecated?
As you can see here, they now recommend this:
val bluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
bluetoothManager.getAdapter()
The reason seems to be that BluetoothAdapter.getDefaultAdapter()
ignores Context, while more complex apps might need to explicitly reference the correct Context.
Not a good reason to deprecate it in my opinion, as I can't think of a realistic/frequent usecase where the BluetoothAdapter needs to be based on the Context. They should have just left both options (Context based and default) in without deprecation.
Related Topics
How to Get Specific Pushedid in Firebase
Android: How to Gain Root Access in an Android Application
Linux Command for Extracting War File
Creating an Array of Objects in Java
Running Code After Spring Boot Starts
How Does Java Do Modulus Calculations with Negative Numbers
How to Convert a String to an Inputstream in Java
How to Create a Custom Appender in Log4J2
Why Double Width = 50/110000; the Output Is 0.000000000000000
How to Check Certificate Name and Alias in Keystore Files
Convert JSONarray to String Array
Why Does My Eclipse Luna 4.4 Crash on Debian Wheezy 7.4 with Oracle Jdk8 64Bit
Java 8: Performance of Streams VS Collections
What Does Statement.Setfetchsize(Nsize) Method Really Do in SQL Server Jdbc Driver
Differencebetween Persist() and Merge() in JPA and Hibernate