Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Android

Cách chạy một phương thức mỗi 10 giây trên Android bằng Kotlin

Giới thiệu

Ví dụ minh họa cách lặp lại thực thi một đoạn code (phương thức) mỗi 10 giây sử dụng Handler và Runnable trong Kotlin Android. Cách này phù hợp cho các tác vụ nhẹ, cập nhật UI định kỳ.

Các bước thực hiện

Bước 1: Tạo dự án mới

Android Studio > File > New Project.

Bước 2: Layout (activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="70dp"
        android:background="#008080"
        android:padding="5dp"
        android:text="TutorialsPoint"
        android:textColor="#fff"
        android:textSize="24sp"
        android:textStyle="bold" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="Chạy phương thức mỗi 10 giây"
        android:textColor="@android:color/holo_orange_dark"
        android:textSize="16sp"
        android:textStyle="bold" />

</RelativeLayout>

Bước 3: MainActivity.kt - Handler & Runnable

import android.os.Bundle
import android.os.Handler
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    private val handler = Handler()
    private var runnable: Runnable? = null
    private val delay = 10000L // 10 giây = 10,000 ms

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        title = "KotlinApp"
    }

    override fun onResume() {
        super.onResume()
        startPeriodicTask()
    }

    override fun onPause() {
        super.onPause()
        stopPeriodicTask()
    }

    private fun startPeriodicTask() {
        runnable = Runnable {
            // Thực hiện tác vụ tại đây
            Toast.makeText(this@MainActivity, "Phương thức chạy mỗi 10 giây", Toast.LENGTH_SHORT).show()
            // Lên lịch lần sau
            handler.postDelayed(runnable!!, delay)
        }
        // Khởi chạy lần đầu
        handler.postDelayed(runnable!!, delay)
    }

    private fun stopPeriodicTask() {
        runnable?.let { handler.removeCallbacks(it) }
        runnable = null
    }
}

Bước 4: AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="com.example.periodictask">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
</manifest>

Chạy ứng dụng

Chạy app, mỗi 10 giây Toast sẽ hiện lên. Khi app vào background (onPause), task dừng; về foreground (onResume), task tiếp tục.

Các giải pháp thay thế hiện đại

1. Kotlin Coroutines (Khuyến nghị cho tác vụ nền)

// Trong ViewModel hoặc Lifecycle-aware component
viewModelScope.launch {
    while (true) {
        delay(10_000) // 10 giây
        // Thực hiện tác vụ nền (network, db)
        // withContext(Dispatchers.Main) { updateUI() } // Nếu cập nhật UI
    }
}
  • Tự động hủy khi Lifecycle destroyed (viewModelScope).
  • Dễ dàng điều khiển (pause, cancel), xử lý exception.
  • Không rò rỉ bộ nhớ như Handler nếu quên removeCallbacks.

2. WorkManager (Cho tác vụ đảm bảo thực thi, даже khi app kill)

val request = PeriodicWorkRequestBuilder(15, TimeUnit.MINUTES) // Min 15 phút
    .build()
WorkManager.getInstance(context).enqueue(request)
  • Đảm bảo chạy sau reboot, doze mode.
  • Chu kỳ tối thiểu 15 phút (không dùng cho 10 giây).

3. AlarmManager + BroadcastReceiver (Định kỳ chính xác, system-level)

Phức tạp hơn, dùng cho alarm, reminder chính xác.

Lưu ý quan trọng với Handler

  • Luôn removeCallbacks trong onPause/onDestroy để tránh leak memory và crash khi Activity đã hủy nhưng Runnable vẫn chạy.
  • Handler chạy trên Main Thread (UI Thread). Tác vụ nặng phải dùng Handler(Looper.getMainLooper()) post lên background thread hoặc dùng Coroutines.
  • Không dùng cho interval quá ngắn (dưới 16ms) - gây lag UI.