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

Chạy phương thức định kỳ mỗi 10 giây trên Android

Giới thiệu

Bài viết này hướng dẫn cách thực thi một phương thức (method) lặp lại mỗi 10 giây trên Android bằng cách sử dụng Handler và Runnable. Đây là cách phổ biến cho các tác vụ định kỳ nhẹ trên UI thread.

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

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

Mở Android Studio, chọn File → New Project và điền thông tin cần thiết.

Bước 2: Thiết kế giao diện (res/layout/activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:gravity="center"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:textSize="24sp" />

</LinearLayout>

Bước 3: Viết code lặp định kỳ (src/MainActivity.java)

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

public class MainActivity extends AppCompatActivity {

    private Handler handler;
    private Runnable runnable;
    private final int delay = 10000; // 10 giây = 10,000 ms

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        // Khởi tạo Handler gắn với Main Looper (UI thread)
        handler = new Handler(Looper.getMainLooper());
    }

    @Override
    protected void onResume() {
        super.onResume();
        startPeriodicTask();
    }

    @Override
    protected void onPause() {
        super.onPause();
        stopPeriodicTask();
    }

    private void startPeriodicTask() {
        runnable = new Runnable() {
            @Override
            public void run() {
                // Thực hiện công việc ở đây
                doPeriodicWork();
                
                // Lên lịch chạy lại sau 10 giây
                handler.postDelayed(this, delay);
            }
        };
        // Khởi chạy lần đầu
        handler.post(runnable);
    }

    private void stopPeriodicTask() {
        if (handler != null && runnable != null) {
            handler.removeCallbacks(runnable);
            runnable = null;
        }
    }

    private void doPeriodicWork() {
        // Ví dụ: Hiển thị Toast mỗi 10 giây
        Toast.makeText(this, "Phương thức chạy mỗi 10 giây", Toast.LENGTH_SHORT).show();
        
        // Thực tế: gọi API, cập nhật UI, sync dữ liệu, check trạng thái...
    }
}

Bước 4: Cấu hình Manifest (androidManifest.xml)

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

    <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>
                
                
            </intent-filter>
        </activity>

    </application>
</manifest>

Chạy ứng dụng

Kết nối thiết bị, nhấn Run. Mỗi 10 giây sẽ hiển thị một Toast. Test bằng cách đưa app vào background (nhấn Home) - Toast sẽ dừng, quay lại app - Toast tiếp tục.

So sánh các phương pháp chạy định kỳ

Phương pháp Ưu điểm Nhược điểm Phù hợp cho
Handler + Runnable Đơn giản, chạy trên UI thread, dễ cập nhật UI Dừng khi app background, không chính xác nếu tác vụ nặng Cập nhật UI nhẹ, polling ngắn hạn
ScheduledExecutorService Chạy background thread, chính xác hơn Cần chuyển về UI thread để cập nhật view Tác vụ nặng, không liên quan UI
WorkManager Đảm bảo chạy được ngay cả khi app kill, hệ thống tối ưu pin Không chính xác về thời điểm (deferred), phức tạp hơn Sync dữ liệu, backup, tác vụ quan trọng
AlarmManager + BroadcastReceiver Đánh thức app từ background, chính xác (setExact) Phức tạp, cần permission từ API 31+, tiêu tốn pin Nhắc nhở, alarm, tác vụ thời gian thực
Kotlin Coroutines + Flow Hiện đại, structured concurrency, dễ hủy, test Yêu cầu Kotlin, hiểu về coroutine scope Dự án Kotlin mới, logic phức tạp

Ví dụ với Kotlin Coroutines (Khuyên dùng cho dự án mới)

// Trong ViewModel hoặc Lifecycle-aware component
viewModelScope.launch {
    while (true) {
        doPeriodicWork() // suspend function hoặc withContext(Dispatchers.IO)
        delay(10_000) // 10 giây, tự động hủy khi viewModelScope bị clear
    }
}

Lưu ý quan trọng

  • Luôn dừng trong onPause()/onStop(): Tránh leak và crash khi Activity bị destroy.
  • Handler(Looper.getMainLooper()): Khai báo rõ ràng từ API 30+, tránh warning.
  • Không làm tác vụ nặng trong Runnable: Sẽ gây lag UI. Dùng withContext(Dispatchers.IO) hoặc ExecutorService.
  • WorkManager là lựa chọn tốt nhất cho tác vụ cần đảm bảo thực thi (sync, upload log...).
  • Tránh TimerTask - đã lỗi thời và không quản lý vòng đời Android.