Synchronized List trong Android ListView
Bài viết này hướng dẫn sử dụng Collections.synchronizedList() để tạo danh sách an toàn luồng (thread-safe) cho ListView. Điều này quan trọng khi danh sách được truy cập từ nhiều luồng cùng lúc.
Bước 1: Tạo dự án mới
Android Studio → File → New Project.
Bước 2: 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:orientation="vertical"
android:gravity="center_horizontal"
android:layout_marginTop="30dp"
tools:context=".MainActivity">
<EditText
android:id="@+id/edit_query"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/buttonPanel"
android:text="Check"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ListView
android:id="@+id/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Bước 3: Code logic (src/MainActivity.java)
package com.example.myapplication;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
public class MainActivity extends AppCompatActivity {
ListView list;
String[] mobileArray = {"Android", "IPhone", "WindowsMobile", "Blackberry",
"WebOS", "Ubuntu", "Windows7", "Max OS X"};
EditText edit_query;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edit_query = findViewById(R.id.edit_query);
list = findViewById(R.id.list);
final ArrayList<String> arrayList = new ArrayList<>(Arrays.asList(mobileArray));
// Adapter ban đầu với synchronized list
ArrayAdapter adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
Collections.synchronizedList(arrayList));
list.setAdapter(adapter);
findViewById(R.id.buttonPanel).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String input = edit_query.getText().toString().trim();
if (!input.isEmpty()) {
// Kiểm tra trùng lặp (cần synchronized khi đọc)
synchronized (arrayList) {
if (arrayList.contains(input)) {
Toast.makeText(MainActivity.this,
"Đã có trong danh sách", Toast.LENGTH_LONG).show();
} else {
arrayList.add(input);
// Cập nhật adapter
ArrayAdapter newAdapter = new ArrayAdapter<String>(MainActivity.this,
android.R.layout.simple_list_item_1,
Collections.synchronizedList(arrayList));
list.setAdapter(newAdapter);
}
}
}
}
});
}
}
Lưu ý quan trọng về Synchronized List
Collections.synchronizedList()chỉ đồng bộ hóa các phương thức riêng lẻ.- Khi lặp qua list hoặc thực hiện nhiều thao tác liên tiếp (như check-then-add), phải synchronized thủ công trên đối tượng list gốc.
- Trong Android, UI chỉ chạy trên main thread, nên synchronized list ít khi cần thiết trừ khi có background thread sửa đổi dữ liệu.
Chạy ứng dụng
Nhập tên hệ điều hành vào EditText, nhấn "Check". Nếu chưa có → thêm vào list. Nếu đã có → hiện Toast thông báo.
