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

Làm mới (Refresh) Singleton class mỗi 1 giờ trong Android

Mục tiêu

Tự động tạo instance Singleton mới mỗi 1 giờ để reset dữ liệu/cache, đảm bảo dữ liệu không bị lỗi thời.

Cách tiếp cận

Sử dụng Timer + TimerTask chạy nền, mỗi 1 giờ (3.600.000 ms) gán instance mới trong block synchronized để thread-safe.

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

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

Android Studio → File → New Project → Empty Activity.

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

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    android:padding="24dp">

    <Button
        android:id="@+id/btnRefresh"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Refresh Singleton (Test)" />

</LinearLayout>

Bước 3: SingleTonExample.java với auto-refresh

package com.example.singletonrefresh;

import android.content.Context;
import java.util.Timer;
import java.util.TimerTask;

public class SingleTonExample {

    // Instancevolatile để đảm bảo visibility giữa các thread
    private static volatile SingleTonExample instance = new SingleTonExample();
    private Context appContext;

    // Static initializer: chạy 1 lần khi class load
    static {
        Timer timer = new Timer(true); // daemon thread
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                synchronized (SingleTonExample.class) {
                    instance = new SingleTonExample(); // Tạo instance mới
                    // Instance cũ sẽ bị GC dọn dẹp nếu không còn reference
                }
            }
        }, 60 * 60 * 1000L, 60 * 60 * 1000L); // delay 1h, period 1h
    }

    private SingleTonExample() {}

    public static synchronized SingleTonExample getInstance() {
        return instance;
    }

    public void init(Context context) {
        if (appContext == null) {
            this.appContext = context.getApplicationContext();
        }
    }

    public static Context getGlobalContext() {
        return getInstance().appContext;
    }
    
    // Thêm dữ liệu test
    private String testData = "Instance tạo lúc: " + java.time.Instant.now();
    public String getTestData() { return testData; }
}

Bước 4: MainActivity.java

package com.example.singletonrefresh;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    private Button btnRefresh;
    private SingleTonExample singleton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnRefresh = findViewById(R.id.btnRefresh);
        singleton = SingleTonExample.getInstance();
        singleton.init(getApplicationContext());

        btnRefresh.setOnClickListener(v -> 
            Toast.makeText(this, "Dữ liệu hiện tại: " + singleton.getTestData(), Toast.LENGTH_LONG).show()
        );
    }
}

Kết quả

Mỗi 1 giờ, instance Singleton tự động được thay thế. Nhấn nút test sẽ thấy timestamp thay đổi sau 1 giờ.

Làm mới (Refresh) Singleton class mỗi 1 giờ trong Android

Làm mới (Refresh) Singleton class mỗi 1 giờ trong Android

⚠️ Vấn đề & Giải pháp tốt hơn

Vấn đề với Timer trong Android:

  • Timer có thể bị kill khi app vào background/doze mode
  • Không bền vững qua reboot thiết bị
  • Static initializer chỉ chạy 1 lần per process lifetime

Giải pháp Production: WorkManager

// Trong class Application.onCreate()
PeriodicWorkRequest refreshWork = new PeriodicWorkRequest.Builder(
    SingletonRefreshWorker.class, 1, TimeUnit.HOURS)
    .build();
WorkManager.getInstance(this).enqueueUniquePeriodicWork(
    "singleton_refresh", ExistingPeriodicWorkPolicy.KEEP, refreshWork);
public class SingletonRefreshWorker extends CoroutineWorker {
    @Override
    public Result doWork() {
        SingleTonExample.refreshInstance(); // static method tạo instance mới
        return Result.success();
    }
}

Thêm method refreshInstance() vào Singleton:

public static synchronized void refreshInstance() {
    instance = new SingleTonExample();
}

Khi nào dùng auto-refresh Singleton?

  • Cache token hết hạn (access token, refresh token)
  • Dữ liệu cấu hình từ server thay đổi định kỳ
  • Session user timeout
  • Reset bộ nhớ đệm tránh memory leak