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

Lưu HashMap vào Singleton với Global Context trong Android

Singleton Pattern là gì?

Singleton là design pattern đảm bảo một class chỉ có duy nhất 1 instance toàn ứng dụng. Dùng để: kiểm soát truy cập đồng thời, tạo điểm truy cập tập trung cho dữ liệu chia sẻ (cache, config, session...).

Mục tiêu

Tạo class Singleton chứa HashMap<String, Double> để lưu trữ dữ liệu key-value toàn cục, truy cập được từ bất kỳ đâu trong app.

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 đơn giản (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/btnSaveHashMap"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Lưu HashMap vào Singleton" />

</LinearLayout>

Bước 3: Tạo class SingleTonExample.java

package com.example.singletonhashmap;

import android.content.Context;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class SingleTonExample {

    // Instance duy nhất (eager initialization - thread-safe)
    private static final SingleTonExample INSTANCE = new SingleTonExample();

    // Dữ liệu lưu trữ
    private final Map<String, Double> dataMap = new HashMap<>();
    private Context appContext;

    // Private constructor ngăn tạo instance từ bên ngoài
    private SingleTonExample() {}

    // Điểm truy cập toàn cục
    public static synchronized SingleTonExample getInstance() {
        return INSTANCE;
    }

    // Khởi tạo context (gọi 1 lần trong Application hoặc MainActivity)
    public void init(Context context) {
        if (appContext == null) {
            this.appContext = context.getApplicationContext(); // Dùng Application context tránh leak
        }
    }

    // Lấy context toàn cục (dùng cho Toast, Resource, v.v.)
    public static Context getGlobalContext() {
        return getInstance().appContext;
    }

    // Thêm/cập nhật entry
    public void put(String key, double value) {
        dataMap.put(key, value);
    }

    // Lấy giá trị
    public Double get(String key) {
        return dataMap.get(key);
    }

    // Lấy toàn bộ map (để hiển thị/debug)
    public String getHashMapString() {
        return dataMap.toString();
    }

    // Xóa toàn bộ
    public void clear() {
        dataMap.clear();
    }
}

Bước 4: MainActivity.java

package com.example.singletonhashmap;

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 btnSave;
    private SingleTonExample singleton;

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

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

        btnSave.setOnClickListener(v -> {
            // Lưu dữ liệu vào Singleton
            singleton.put("paper", 10.0);
            singleton.put("recharge", 25.5);
            singleton.put("other_bills", 100.0);

            // Hiển thị kết quả qua Toast dùng global context
            Toast.makeText(
                SingleTonExample.getGlobalContext(), 
                "Đã lưu: " + singleton.getHashMapString(), 
                Toast.LENGTH_LONG
            ).show();
        });
    }
}

Kết quả

Nhấn nút → Toast hiển thị: Đã lưu: {paper=10.0, recharge=25.5, other_bills=100.0}

Lưu HashMap vào Singleton với Global Context trong Android

Lưu HashMap vào Singleton với Global Context trong Android

Best Practices cho Singleton Android

  • Luôn dùng context.getApplicationContext() để tránh memory leak Activity
  • Khởi tạo Singleton trong class Application (override onCreate()) để sẵn sàng toàn app
  • Cân nhắc dependency injection (Hilt/Dagger) thay vì Singleton thủ công cho project lớn
  • Thread-safety: HashMap không thread-safe → dùng ConcurrentHashMap nếu multi-thread truy cập
  • Tránh lưu object nặng (Bitmap, Cursor) trong Singleton → OOM

Mở rộng: Singleton trong class Application

public class MyApp extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        SingleTonExample.getInstance().init(this);
    }
}

Khai báo trong Manifest: <application android:name=".MyApp" ...>