Giới thiệu
Bài viết này trình bày cách thoát hoàn toàn ứng dụng (đóng tất cả Activity) bằng cách gọi Process.killProcess(Process.myPid()) trong onDestroy() của Activity cuối cùng. Đây là cách "cứng" và không được khuyến nghị cho ứng dụng thực tế vì vi phạm vòng đời Android, nhưng hữu ích cho mục đích học tập.
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à tạo dự án.
Bước 2: Layout Activity chính (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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@id/button"
android:layout_marginBottom="20dp"
android:gravity="center"
android:text="Activity Chính" />
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Mở Activity Thứ Hai" />
</RelativeLayout>
Bước 3: Code Activity chính (src/MainActivity.java)
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = findViewById(R.id.button);
button.setOnClickListener(v -> {
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivity(intent);
});
}
}
Bước 4: Layout Activity thứ hai (res/layout/activity_second.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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SecondActivity">
<Button
android:id="@+id/terminateButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Đóng tất cả Activity" />
</RelativeLayout>
Bước 5: Code Activity thứ hai (src/SecondActivity.java)
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.os.Process;
public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Button button = findViewById(R.id.terminateButton);
button.setOnClickListener(v -> finish());
}
@Override
protected void onDestroy() {
super.onDestroy();
// CẢNH BÁO: Cách này kill tiến trình ngay lập tức
Process.killProcess(Process.myPid());
}
}
Bước 6: Cấu hình 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>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".SecondActivity" />
</application>
</manifest>
Chạy ứng dụng
Kết nối thiết bị, nhấn Run. Mở Activity 2, nhấn "Đóng tất cả Activity" -> App thoát hoàn toàn, tiến trình bị kill.
⚠️ CẢNH BÁO QUAN TRỌNG
Không nên dùng cách này trong ứng dụng thực tế vì:
- Vi phạm vòng đời Android – hệ thống tự quản lý tiến trình
- Không gọi
onDestroy()của các Activity khác trong stack - Có thể gây rò rỉ tài nguyên, crash, hoặc hành vi bất ngờ
- Android có thể restart tiến trình ngay lập tức (ví dụ: do BroadcastReceiver, Service...)
Các cách đúng đắn (Best Practice)
1. Dùng FLAG_ACTIVITY_CLEAR_TASK + FLAG_ACTIVITY_NEW_TASK (API 11+)
Intent intent = new Intent(this, MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent);
2. Dùng ActivityCompat.finishAffinity() (API 16+)
ActivityCompat.finishAffinity(this); // Đóng Activity hiện tại và tất cả parent
3. Đăng ký callback Application.ActivityLifecycleCallbacks để quản lý stack
Quản lý danh sách Activity sống, gọi finish() trên tất cả khi cần thoát.
4. Đơn giản: chuyển về Home screen
Intent homeIntent = new Intent(Intent.ACTION_MAIN); homeIntent.addCategory(Intent.CATEGORY_HOME); homeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(homeIntent);