How to solve Handler() deprecated?

后端 未结 12 1724
眼角桃花
眼角桃花 2020-12-05 09:00

Could anyone know, how to fix the deprecated warning or any alternate solution for this.

Handler().postDelayed({
    context?.let {
        //code
    }
}, 30         


        
相关标签:
12条回答
  • 2020-12-05 09:47

    The deprecated function is that constructor for Handler. Use Handler(Looper.myLooper()) .postDelayed(runnable, delay) instead

    0 讨论(0)
  • 2020-12-05 09:48

    use this

    Looper.myLooper()?.let {
        Handler(it).postDelayed({
            //Your Code
        },2500)
    }
    
    0 讨论(0)
  • 2020-12-05 09:50

    Provide a looper in the Handler Constructor

    Handler(Looper.getMainLooper())
    
    0 讨论(0)
  • 2020-12-05 09:52

    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)
    
    0 讨论(0)
  • 2020-12-05 09:52

    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.

    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. Execute code in a background thread

    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.

    • Handler(Looper)

    • Handler(Looper, Handler.Callback)

    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. Handler with a Looper and a Handler.Callback

    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
    })
    

    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.

    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
    })
    
    0 讨论(0)
  • 2020-12-05 09:56

    Use Executor instead of handler for more info Executor.
    To achieve post delay use ScheduledExecutorService:

    ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();
    Runnable runnable = () -> {
        public void run() {
            // Do something
        }
    };
    worker.schedule(runnable, 2000, TimeUnit.MILLISECONDS);
    
    0 讨论(0)
提交回复
热议问题