Activity
1. Giới thiệu
Phần tiêu đề “1. Giới thiệu”Lớp Activity là một thành phần quan trọng của ứng dụng Android, và cách các activity được khởi chạy và kết hợp với nhau là một phần cơ bản trong mô hình ứng dụng của nền tảng Android. Khác với các mô hình lập trình khác nơi ứng dụng được khởi chạy bằng phương thức main(), hệ thống Android khởi tạo code trong một instance của Activity bằng cách gọi các callback methods tương ứng với các giai đoạn cụ thể trong vòng đời của nó.
2. Khái niệm về Activity
Phần tiêu đề “2. Khái niệm về Activity”Trải nghiệm ứng dụng di động khác với desktop ở chỗ tương tác của người dùng với ứng dụng không phải lúc nào cũng bắt đầu từ cùng một nơi. Thay vào đó, hành trình của người dùng thường bắt đầu một cách không xác định. Ví dụ:
- Nếu bạn mở ứng dụng email từ màn hình chính, bạn có thể thấy danh sách email
- Nếu bạn đang sử dụng ứng dụng mạng xã hội và nó khởi động ứng dụng email, bạn có thể đi thẳng đến màn hình soạn email
Lớp Activity được thiết kế để hỗ trợ mô hình này. Khi một ứng dụng gọi ứng dụng khác, ứng dụng gọi sẽ gọi một activity trong ứng dụng kia, thay vì toàn bộ ứng dụng. Theo cách này, activity đóng vai trò là điểm vào (entry point) cho tương tác của ứng dụng với người dùng.
Đặc điểm chính của Activity
Phần tiêu đề “Đặc điểm chính của Activity”| Đặc điểm | Mô tả |
|---|---|
| Window | Activity cung cấp cửa sổ để ứng dụng vẽ UI |
| Full-screen | Thường chiếm toàn bộ màn hình, nhưng có thể nhỏ hơn (floating windows) |
| Multi-window | Có thể hiển thị trong chế độ đa cửa sổ |
| One screen | Thông thường, một activity triển khai một màn hình trong ứng dụng |
public class Activity extends ContextThemeWrapper implements ComponentCallbacks2, KeyEvent.Callback, LayoutInflater.Factory2, View.OnCreateContextMenuListener, Window.Callback3. Activity Stack
Phần tiêu đề “3. Activity Stack”Các activity trong hệ thống được quản lý như activity stacks. Khi một activity mới được khởi chạy, nó thường được đặt lên trên cùng của stack hiện tại và trở thành running activity — activity trước đó luôn nằm bên dưới trong stack và sẽ không quay lại foreground cho đến khi activity mới kết thúc.
4 trạng thái của Activity
Phần tiêu đề “4 trạng thái của Activity”flowchart LR A["🟢 Active/Running"] --> B["🟡 Visible"] B --> C["🔴 Stopped/Hidden"] C --> D["⚫ Destroyed"]
style A fill:#4CAF50,stroke:#2E7D32,color:#fff style B fill:#FFC107,stroke:#FFA000,color:#000 style C fill:#f44336,stroke:#c62828,color:#fff style D fill:#424242,stroke:#212121,color:#fff| Trạng thái | Mô tả |
|---|---|
| Active/Running | Activity ở foreground của màn hình (vị trí cao nhất của stack). Đây là activity mà người dùng đang tương tác. |
| Visible | Activity đã mất focus nhưng vẫn hiển thị với người dùng. Điều này xảy ra khi một activity không full-screen hoặc trong suốt nằm trên activity của bạn. |
| Stopped/Hidden | Activity bị che hoàn toàn bởi activity khác. Nó vẫn giữ tất cả state và thông tin, nhưng không còn hiển thị cho người dùng và thường bị hệ thống kill khi cần bộ nhớ. |
| Destroyed | Hệ thống có thể huỷ activity khỏi bộ nhớ bằng cách yêu cầu nó finish, hoặc đơn giản là kill process của nó. Khi hiển thị lại cho người dùng, activity phải được khởi động lại hoàn toàn. |
4. Khai báo Activity trong Manifest
Phần tiêu đề “4. Khai báo Activity trong Manifest”Để ứng dụng có thể sử dụng activity, bạn phải khai báo activity và một số thuộc tính của nó trong AndroidManifest.xml.
Khai báo cơ bản
Phần tiêu đề “Khai báo cơ bản”<manifest ... > <application ... > <activity android:name=".ExampleActivity" /> ... </application ... > ...</manifest >Khai báo Main Activity
Phần tiêu đề “Khai báo Main Activity”<activity android:name=".MainActivity" android:exported="true" android:label="@string/app_name" android:theme="@style/Theme.MyApp"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter></activity>Khai báo Intent Filters
Phần tiêu đề “Khai báo Intent Filters”Intent filters cho phép khởi chạy activity dựa trên cả yêu cầu explicit lẫn implicit:
- Explicit: “Khởi động activity Send Email trong ứng dụng Gmail”
- Implicit: “Khởi động màn hình Send Email trong bất kỳ activity nào có thể thực hiện công việc này”
<activity android:name=".ExampleActivity" android:icon="@drawable/app_icon"> <intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter></activity>Khai báo Permissions
Phần tiêu đề “Khai báo Permissions”<!-- Activity yêu cầu permission để được gọi --><activity android:name=".ShareActivity" android:permission="com.myapp.permission.SHARE_POST" />5. Tạo Activity cơ bản
Phần tiêu đề “5. Tạo Activity cơ bản”Với Jetpack Compose (Recommended)
Phần tiêu đề “Với Jetpack Compose (Recommended)”class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { MyAppTheme { Surface( modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background ) { Greeting("Android") } } } }}
@Composablefun Greeting(name: String, modifier: Modifier = Modifier) { Text( text = "Hello, $name!", modifier = modifier )}Với XML Views (Legacy)
Phần tiêu đề “Với XML Views (Legacy)”class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main)
// Sử dụng findViewById để lấy views val textView = findViewById<TextView>(R.id.textView) textView.text = "Hello, Android!" }}6. Ba Vòng đời quan trọng
Phần tiêu đề “6. Ba Vòng đời quan trọng”Activity có 3 key loops bạn cần quan tâm:
Entire Lifetime
Phần tiêu đề “Entire Lifetime”Xảy ra giữa lần gọi đầu tiên onCreate() đến lần gọi cuối cùng onDestroy().
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Setup "global" state, tạo background thread}
override fun onDestroy() { super.onDestroy() // Release tất cả resources}Visible Lifetime
Phần tiêu đề “Visible Lifetime”Xảy ra giữa onStart() và onStop(). Trong thời gian này, người dùng có thể thấy activity trên màn hình.
override fun onStart() { super.onStart() // Register BroadcastReceiver để monitor UI changes}
override fun onStop() { super.onStop() // Unregister BroadcastReceiver}Foreground Lifetime
Phần tiêu đề “Foreground Lifetime”Xảy ra giữa onResume() và onPause(). Trong thời gian này, activity đang visible, active và tương tác với người dùng.
override fun onResume() { super.onResume() // Activity đang tương tác với user}
override fun onPause() { super.onPause() // Pause operations, nhưng code nên lightweight}7. Khởi động Activity khác
Phần tiêu đề “7. Khởi động Activity khác”Sử dụng Intent
Phần tiêu đề “Sử dụng Intent”// Explicit Intentval intent = Intent(this, DetailActivity::class.java).apply { putExtra("user_id", 123) putExtra("user_name", "Alice")}startActivity(intent)Nhận dữ liệu
Phần tiêu đề “Nhận dữ liệu”class DetailActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState)
val userId = intent.getIntExtra("user_id", 0) val userName = intent.getStringExtra("user_name") ?: ""
setContent { DetailScreen(userId, userName) } }}Implicit Intent
Phần tiêu đề “Implicit Intent”val sendIntent = Intent().apply { action = Intent.ACTION_SEND type = "text/plain" putExtra(Intent.EXTRA_TEXT, textMessage)}startActivity(sendIntent)8. Kết thúc Activity
Phần tiêu đề “8. Kết thúc Activity”// Kết thúc Activity hiện tạifinish()
// Kết thúc và xóa toàn bộ task stackfinishAffinity()
// Kết thúc với resultsetResult(Activity.RESULT_OK, Intent().apply { putExtra("result", "Success")})finish()9. Launch Modes
Phần tiêu đề “9. Launch Modes”<!-- standard: Mặc định, Activity mới được thêm vào stack --><activity android:launchMode="standard" ... />
<!-- singleTop: Tái sử dụng nếu đã ở top của stack --><activity android:launchMode="singleTop" ... />
<!-- singleTask: Một instance duy nhất trong task --><activity android:launchMode="singleTask" ... />
<!-- singleInstance: Task riêng biệt, instance duy nhất --><activity android:launchMode="singleInstance" ... />10. Activity với ViewModel
Phần tiêu đề “10. Activity với ViewModel”class MainActivity : ComponentActivity() { private val viewModel: MainViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState)
setContent { val uiState by viewModel.uiState.collectAsState()
MainScreen( state = uiState, onEvent = viewModel::onEvent ) } }}📝 Tóm tắt
Phần tiêu đề “📝 Tóm tắt”| Khái niệm | Mô tả |
|---|---|
| Activity | Thành phần UI cơ bản, đại diện cho một màn hình |
| Entry Point | Activity là điểm vào cho tương tác với người dùng |
| Activity Stack | Các activity được quản lý trong stack (LIFO) |
| 4 States | Active, Visible, Stopped, Destroyed |
| Manifest | Activity phải được khai báo trong AndroidManifest.xml |
| Intent Filters | Cho phép activity respond với implicit intents |
📚 Tham khảo: