aedev.net
  • Trang chủ
  • AI
  • Mobile
  • Flutter
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
No Result
View All Result
SAVED POSTS
aedev.net
  • Trang chủ
  • AI
  • Mobile
  • Flutter
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
No Result
View All Result
aedev.net
No Result
View All Result
Minh họa môi trường phát triển React Native với laptop, Android emulator và iOS simulator

Android runOnUiThread và Handler.post: chạy ngay hay đưa vào hàng đợi?

Suong Nguyen by Suong Nguyen
10/11/2026
in Lập trình Mobile
0
585
SHARES
3.2k
VIEWS
Summarize with ChatGPTShare to Facebook

Một đoạn code kỳ vọng callback cập nhật UI chạy sau dòng kế tiếp, nhưng thứ tự quan sát lại ngược lại. Nếu lời gọi là runOnUiThread và bạn đã đứng trên UI thread, callback có thể được thực hiện ngay. Tên hàm nói về thread đích, không tự có nghĩa luôn trì hoãn công việc sang hàng đợi.

Bài đối chiếu Android API reference ngày 10/11/2026. Các API trong ví dụ có từ API level 1. Code Kotlin dành cho Android Views được rà theo tài liệu, chưa biên dịch bằng Android SDK, chạy emulator, thiết bị hoặc đo thứ tự log thực tế. Các chuỗi thứ tự dưới đây là kỳ vọng cần kiểm tra theo hợp đồng API.

Hai đường đi khi caller đã ở main thread

Activity.runOnUiThread quy định action chạy ngay nếu thread hiện tại là UI thread; nếu không, action được đưa vào event queue của UI thread. Vì thế, cùng một hàm có thể có cách thực thi khác tùy nơi gọi.

Handler.post đưa Runnable vào message queue gắn với Handler. Ví dụ tạo Handler bằng main Looper để nói rõ thread đích, thay vì dựa vào một constructor tự đoán Looper.

Dùng hai nút để quan sát riêng từng đường

Đặt Activity này trong package dự án thử nghiệm, khai báo Activity trong manifest theo ứng dụng của bạn. Mỗi lần thử chỉ bấm một nút rồi đọc kết quả:

import android.app.Activity
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.widget.Button
import android.widget.LinearLayout
import android.widget.TextView

class UiQueueDemoActivity : Activity() {
    private val handler = Handler(Looper.getMainLooper())

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val report = TextView(this)
        val immediate = Button(this).apply {
            text = "runOnUiThread"
            setOnClickListener {
                val trace = mutableListOf("before")
                runOnUiThread { trace.add("inside") }
                trace.add("after")
                report.text = trace.joinToString(" -> ")
            }
        }
        val queued = Button(this).apply {
            text = "Handler.post"
            setOnClickListener {
                val trace = mutableListOf("before")
                val accepted = handler.post {
                    trace.add("inside")
                    report.text = trace.joinToString(" -> ")
                }
                trace.add("after")
                report.text = trace.joinToString(" -> ")
                if (!accepted) report.text = "Không đưa được vào hàng đợi"
            }
        }
        val content = LinearLayout(this).apply {
            orientation = LinearLayout.VERTICAL
            addView(immediate)
            addView(queued)
            addView(report)
        }
        setContentView(content)
    }

    override fun onDestroy() {
        handler.removeCallbacksAndMessages(null)
        super.onDestroy()
    }
}

Hai callback của nút được framework gọi trên UI thread trong tình huống màn hình thông thường. Với runOnUiThread, thứ tự cần quan sát là before, inside, after. Với Handler.post được chấp nhận vào queue, khi Runnable được xử lý, trace dự định là before, after, inside. Dòng report trước đó có thể đã được ghi với hai phần tử; không coi nó là một phép đo frame hoặc bằng chứng chắc chắn người dùng đã nhìn thấy trạng thái trung gian.

Post thành công chưa có nghĩa công việc đã hoàn tất

Giá trị boolean của post cho biết Runnable có được đưa vào queue hay không. Nó không chứa kết quả của Runnable và không chứng minh callback đã chạy xong. Tài liệu nêu trường hợp Looper đang thoát có thể khiến thao tác đưa vào queue thất bại.

Trong demo, Handler thuộc riêng Activity và callbacks được dọn ở onDestroy. Đây chỉ là ví dụ nhỏ để quan sát thứ tự; nó không triển khai một cơ chế lưu việc qua process death hoặc khôi phục màn hình. Khi công việc có vòng đời dài, cần thiết kế nơi sở hữu và hủy công việc phù hợp với ứng dụng.

Cả hai đều không tự chuyển tác vụ nặng sang background

Handler được gắn main Looper nên Runnable của nó vẫn chạy trên main thread. Đổi từ runOnUiThread sang post không làm phép xử lý ảnh hoặc vòng lặp nặng trở thành công việc background. Nó chỉ đổi cách đặt action vào luồng thực thi ở trường hợp đang bàn.

Không dùng Thread.sleep trên UI thread để cố tạo ra thứ tự mong muốn trong bài thử. Mục tiêu là hiểu hợp đồng lập lịch, không làm màn hình đứng để có một log dễ nhìn hơn. Nếu cần hoàn thành một việc rồi mới làm việc sau, chọn một cách biểu diễn phụ thuộc kết quả rõ ràng thay vì suy từ tên API.

Checklist khi điều tra thứ tự

Xác nhận thread ở nơi gọi, Looper của Handler và thời điểm Activity còn hợp lệ. Ghi trace trước, trong và sau callback thay vì chỉ một dòng “đã gọi hàm”. Tách việc đăng Runnable, thực thi Runnable và vẽ giao diện thành những mốc khác nhau trong cách diễn giải.

Thử hai nút riêng trên thiết bị mục tiêu và kiểm tra sau khi rời màn hình. Ví dụ giúp bạn đặt đúng câu hỏi về chạy ngay hay xếp hàng; nó không cam kết thời gian chờ cố định hoặc thay thế kiểm thử vòng đời của sản phẩm.

Nguồn tham khảo

  • Android: Activity.runOnUiThread
  • Android: Handler.post
  • Android: Looper.getMainLooper

Tags: AndroidKotlinMain thread
SummarizeShare234
Suong Nguyen

Suong Nguyen

Related Stories

Minh họa môi trường phát triển React Native với laptop, Android emulator và iOS simulator

Android CheckBox: đổi isChecked bằng code vẫn có thể gọi listener

by Suong Nguyen
09/11/2026
0

Phân biệt sự kiện đổi trạng thái với thao tác bấm của người dùng khi dùng CheckBox và OnCheckedChangeListener trong Android Views.

Minh họa môi trường phát triển React Native với laptop, Android emulator và iOS simulator

Android TextView.setText(Int): số đếm có thể bị hiểu thành resource ID

by Suong Nguyen
08/11/2026
0

Phân biệt overload setText nhận resource ID với overload nhận nội dung để hiển thị số đếm mà không gọi nhầm tài nguyên chuỗi.

Minh họa môi trường phát triển React Native với laptop, Android emulator và iOS simulator

Android elapsedRealtime và uptimeMillis: thời gian máy ngủ có được tính không?

by Suong Nguyen
07/11/2026
0

Chọn đồng hồ đo khoảng thời gian theo yêu cầu có tính deep sleep, và giữ mốc since-boot riêng với timestamp theo lịch.

Minh họa môi trường phát triển React Native với laptop, Android emulator và iOS simulator

Android SharedPreferences.apply: đọc lại được chưa chứng minh đã ghi xong xuống đĩa

by Suong Nguyen
06/11/2026
0

Tách việc cập nhật SharedPreferences trong bộ nhớ khỏi xác nhận lưu bền vững, và kiểm tra đúng phạm vi của apply với commit.

0 0 votes
Article Rating
Subscribe
Login
Notify of
guest
guest
0 Comments
Oldest
Newest Most Voted
AE Dev

AE Dev mang đến các bài viết về lập trình, mobile app, backend, frontend, WordPress và công nghệ, phù hợp cho developer muốn học hỏi và cập nhật kiến thức thực tế.

Recent Posts

  • React Native Text selectable: cho người dùng chọn và sao chép mã hiển thị
  • Phỏng vấn JavaScript: object mặc định của tham số được tạo khi nào?
  • Android runOnUiThread và Handler.post: chạy ngay hay đưa vào hàng đợi?

Categories

  • AI
  • Backend
  • Đánh giá
  • DevOps
  • Flutter
  • Hướng dẫn
  • Lập trình Mobile
  • Phỏng vấn
  • React Native
  • Uncategorized

Weekly Newsletter

  • Buy JNews
  • Support Forum
  • Pre-sale Question
  • Contact Us

© 2026 AE Dev - Blog công nghệ, lập trình và chia sẻ kiến thức IT.

Welcome Back!

Login to your account below

Forgotten Password?

Retrieve your password

Please enter your username or email address to reset your password.

Log In
No Result
View All Result
  • Trang chủ
  • AI
  • Mobile
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
  • Flutter

© 2026 AE Dev - Blog công nghệ, lập trình và chia sẻ kiến thức IT.

wpDiscuz
0
0
Would love your thoughts, please comment.x
()
x
| Reply