Giới thiệu
Bài viết hướng dẫn ghi đè phương thức onBackPressed() để hiển thị AlertDialog xác nhận trước khi thoát Activity, tránh người dùng thoát nhầm.
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: Giao diện (res/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:id="@+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Hộp thoại xác nhận thoát Android Activity"
android:textAlignment="center"
android:textSize="24sp"
android:textStyle="bold" />
</RelativeLayout>
Bước 3: Logic (src/MainActivity.java)
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.content.DialogInterface;
import android.os.Bundle;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public void onBackPressed() {
new AlertDialog.Builder(this)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle("Đóng Activity")
.setMessage("Bạn có chắc chắn muốn đóng Activity này?")
.setPositiveButton("Có", (dialog, which) -> {
finish();
Toast.makeText(MainActivity.this, "Activity đã đóng", Toast.LENGTH_SHORT).show();
})
.setNegativeButton("Không", null)
.show();
}
}
Bước 4: Manifest
<?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>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Chạy ứng dụng
Kết nối thiết bị, nhấn Run. Nhấn nút Back vật lý hoặc gesture back → hiện dialog xác nhận.

Mở rộng: Tùy chỉnh Dialog
Thêm checkbox "Không hỏi lại"
SharedPreferences prefs = getSharedPreferences("exit_pref", MODE_PRIVATE);
boolean showDialog = prefs.getBoolean("show_exit_dialog", true);
@Override
public void onBackPressed() {
if (!showDialog) {
super.onBackPressed();
return;
}
View checkboxView = View.inflate(this, R.layout.dialog_checkbox, null);
CheckBox checkBox = checkboxView.findViewById(R.id.dont_ask_again);
new AlertDialog.Builder(this)
.setView(checkboxView)
.setTitle("Xác nhận thoát")
.setMessage("Bạn có muốn thoát ứng dụng?")
.setPositiveButton("Có", (dialog, which) -> {
if (checkBox.isChecked()) {
prefs.edit().putBoolean("show_exit_dialog", false).apply();
}
finishAffinity(); // Đóng toàn bộ app
})
.setNegativeButton("Không", null)
.show();
}
Layout dialog_checkbox.xml
<?xml version="1.0" encoding="utf-8"?>
<CheckBox xmlns:android="https://schemas.android.com/apk/res/android"
android:id="@+id/dont_ask_again"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Không hỏi lại" />
Lưu ý về onBackPressed()
- Từ Android 13 (API 33), có
OnBackPressedCallback(Activity/Fragment) thay thế override method - Dùng
finishAffinity()để đóng toàn bộ task,finish()chỉ đóng Activity hiện tại - Tránh logic phức tạp trong dialog - giữ gọn nhẹ