Что мне использовать теперь, когда Handler() устарел?
Как мне исправить предупреждение об устаревании в этом коде? В качестве альтернативы, есть ли какие-либо другие варианты для этого?
Handler().postDelayed({
context?.let {
//code
}
}, 3000)
Переведено автоматически
Ответ 1
Только конструктор без параметров устарел, теперь предпочтительнее указывать Looper
в конструкторе с помощью Looper.getMainLooper()
метода.
Используйте ее для Java
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
// Your Code
}
}, 3000);
Используйте ее для Kotlin
Handler(Looper.getMainLooper()).postDelayed({
// Your Code
}, 3000)
Источник : developer.android.com
Ответ 2
Начиная с 30-го уровня API, есть 2 конструктора, которые устарели.
Google объясняет причину ниже.
Неявный выбор циклизатора во время построения обработчика может привести к ошибкам, при которых операции автоматически теряются (если Обработчик не ожидает новых задач и завершает работу), сбоям (если обработчик иногда создается в потоке без активного циклизатора) или условиям гонки, когда поток, с которым связан обработчик, не соответствует ожиданиям автора. Вместо этого используйте Executor или явно укажите Looper, используя Looper#getMainLooper , {link android.view.View#getHandler} или аналогичный. Если для совместимости требуется неявное локальное поведение потока, используйте новый обработчик (Looper.myLooper(), обратный вызов), чтобы читателям было понятно.
Решение 1: Используйте Executor
1. Выполните код в основном потоке.
Java
// 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.
}
});
Kotlin
// Create an executor that executes tasks in the main thread.
val mainExecutor = ContextCompat.getMainExecutor(this)
// Execute a task in the main thread
mainExecutor.execute {
// You code logic goes here.
}
2. Выполнение кода в фоновом потоке
Java
// 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 3 seconds.
backgroundExecutor.schedule(new Runnable() {
@Override
public void run() {
// Your code logic goes here
}
}, 3, TimeUnit.SECONDS);
Kotlin
// Create an executor that executes tasks in a background thread.
val backgroundExecutor: ScheduledExecutorService = Executors.newSingleThreadScheduledExecutor()
// Execute a task in the background thread.
backgroundExecutor.execute {
// Your code logic goes here.
}
// Execute a task in the background thread after 3 seconds.
backgroundExecutor.schedule({
// Your code logic goes here
}, 3, 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.
Java
// 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.
}
});
}
});
Kotlin
// Create an executor that executes tasks in the main thread.
val mainExecutor: Executor = ContextCompat.getMainExecutor(this)
// Create an executor that executes tasks in a background thread.
val backgroundExecutor = Executors.newSingleThreadScheduledExecutor()
// Execute a task in the background thread.
backgroundExecutor.execute {
// Your code logic goes here.
// Update UI on the main thread
mainExecutor.execute {
// You code logic goes here.
}
}
Solution 2: Specify a Looper explicitly by using one of the following constructors.
1. Execute code in the main thread
1.1. Handler with a Looper
Java
Handler mainHandler = new Handler(Looper.getMainLooper());
Kotlin
val mainHandler = Handler(Looper.getMainLooper())
1.2 Handler with a Looper and a Handler.Callback
Java
Handler mainHandler = new Handler(Looper.getMainLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message message) {
// Your code logic goes here.
return true;
}
});
Kotlin
val mainHandler = Handler(Looper.getMainLooper(), Handler.Callback {
// Your code logic goes here.
true
})
2. Execute code in a background thread
2.1. Handler with a Looper
Java
// 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());
Kotlin
// Create a background thread that has a Looper
val handlerThread = HandlerThread("HandlerThread")
handlerThread.start()
// Create a handler to execute tasks in the background thread.
val backgroundHandler = Handler(handlerThread.looper)
2.2. Обработчик с циклом и обработчиком.Обратный вызов
Java
// 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;
}
});
Kotlin
// Create a background thread that has a Looper
val handlerThread = HandlerThread("HandlerThread")
handlerThread.start()
// Create a handler to execute taks in the background thread.
val backgroundHandler = Handler(handlerThread.looper, Handler.Callback {
// Your code logic goes here.
true
})
Примечание: Не забудьте освободить поток после использования.
handlerThread.quit(); // or handlerThread.quitSafely();
3. Выполните код в фоновом потоке и обновите пользовательский интерфейс в основном потоке.
Java
// 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;
}
});
Kotlin
// Create a handler to execute code in the main thread
val mainHandler = Handler(Looper.getMainLooper())
// Create a background thread that has a Looper
val handlerThread = HandlerThread("HandlerThread")
handlerThread.start()
// Create a handler to execute in the background thread
val backgroundHandler = Handler(handlerThread.looper, Handler.Callback {
// Your code logic goes here.
// Update UI on the main thread.
mainHandler.post {
}
true
})
Ответ 3
Если вы хотите избежать проверки null в Kotlin (?
или !!
), вы можете использовать, Looper.getMainLooper()
если ваш Handler
работает с какой-либо функцией, связанной с пользовательским интерфейсом, например, с этим:
Handler(Looper.getMainLooper()).postDelayed({
Toast.makeText(this@MainActivity, "LOOPER", Toast.LENGTH_SHORT).show()
}, 3000)
Примечание: используйте requireContext()
вместо this@MainActivity
, если вы используете fragment.
Ответ 4
Устаревшая функция - это конструктор для Handler. Используйте Handler(Looper.myLooper()) .postDelayed(runnable, delay)
вместо