Giới thiệu
Khi mới bắt đầu lập trình Android, việc bắt đầu là cài đặt thành công Android Studio IDE và tạo project xem trong project được tổ chức ra sao? Mặc định khi khởi tạo project, luôn có 1 cặp file được tạo ra là:
- MainActivity.java
- activity_main.xml
![Tạo project trong Android](https://resources.stdio.vn/content/article/5fa767165f20ad4e0974a9f6/resources/res-1604997112-1604997112652.png)
Activity trong Android là gì?
Activity
trong Android được xem là 1 màn hình tương tác trong ứng dụng Android, Activity
chịu trách nhiệm chuyển giao sự kiện cho các view trong nó và quản lý vòng đời (lifecycle) của nó, 1 ứng dụng Android có thể có 1 hoặc nhiều Activity, những Activity này có vòng đời độc lập với nhau và được duy trì trong Activity Back Stack.
![Activity trong Android](https://resources.stdio.vn/content/article/5fa767165f20ad4e0974a9f6/resources/res-1604997293-1604997294043.png)
- Từ Activity 1 chuyển sang Activity 2, Activty 1 được đẩy xuống dưới stack và Activity 2 nằm trên cùng của Stack.
- Từ Activity 2 chuyển sang Activity 3, Activty 2 được đẩy xuống dưới stack và Activity 3 nằm trên cùng của stack.
- Ở Activty 3 nhấn nút back thì Activity 3 được destroy và đẩy ra khỏi stack, khi đó Activity 2 được đưa lên top của stack.
Vòng đời của Activity
Trước tiên sẽ tìm hiểu vòng đời của Activity sau đó sẽ đi đến phần thực hành để hiểu rõ hơn.
![Vòng đời của ứng dụng Android.](https://resources.stdio.vn/content/article/5fa767165f20ad4e0974a9f6/resources/res-1604997520-1604997520094.png)
onCreate()
onCreate()
tự động được gọi khi ứng dụng mới start nhưng chưa thể tương tác với người dùng. Trong phương thức này thường sử dụng để setContentView()
, khởi tạo view, inflate view từ xml đăng kí event cho view, khởi tạo Adapter cho ListView
, RecyclerView
, ...
onStart()
onStart()
tự động được gọi sau khi onCreate()
được gọi, phương thức này vẫn chưa tương tác được với người dùng trên UI.
onResume()
onResume()
tự động được gọi sau khi onStart()
được gọi, phương thức này tương tác được với UI.
onPause()
onPause()
được sử dụng khá phổ biến trong vòng đời của Activity, thường dùng để lưu lại trạng thái của ứng dụng khi ứng dụng chuẩn bị dừng.
onStop()
onStop()
tự động được gọi sau khi phương thức onPause()
được gọi, phương thức này tự động được gọi khi nhấn nút HOME.
onRestart()
onRestart()
tự động được gọi khi Activity đã ngưng và đang chuẩn bị bắt đầu lại activity.
onDestroy()
onDestroy()
tự động được gọi khi nhấn back từ Activity, hoặc gọi phương thức finish()
của Activity.
Tạo ứng dụng demo vòng đời Activity
Thực hành để tìm hiểu vòng đời của Activity trong Android.
Tạo project ActivityLifeCycle
![Tạo project Android.](https://resources.stdio.vn/content/article/5fa767165f20ad4e0974a9f6/resources/res-1605004304-1605004304335.png)
Chọn API sử dụng trong project (có thể chọn phiên bản mới nhất):
![](https://resources.stdio.vn/content/article/5fa767165f20ad4e0974a9f6/resources/res-1605004402-1605004402538.png)
Nhấn Next và chọn Empty Activity. Android Studio sẽ tạo cho project như sau:
![](https://resources.stdio.vn/content/article/5fa767165f20ad4e0974a9f6/resources/res-1605004776-1605004776456.png)
Khảo sát 1 Activity
class MainActivity
Trước tiên log tất cả các phương thức trong lifecycle và chạy xem các phương thức trên có thứ tự hoạt động ra sao?
Log.e(TAG, "onCreate: ");
Log.e(TAG, "onStart: ");
Log.e(TAG, "onRestart: ");
- ...
package com.example.nguyennghia.activitylifecycle; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.e(TAG, "onCreate: "); } @Override protected void onStart() { super.onStart(); Log.e(TAG, "onStart: "); } @Override protected void onRestart() { super.onRestart(); Log.e(TAG, "onRestart: "); } @Override protected void onResume() { super.onResume(); Log.e(TAG, "onResume: "); } @Override protected void onPause() { super.onPause(); Log.e(TAG, "onPause: "); } @Override protected void onStop() { super.onStop(); Log.e(TAG, "onStop: "); } @Override protected void onDestroy() { super.onDestroy(); Log.e(TAG, "onDestroy: "); } }
Trường hợp 1: Start lên và nhấn back để thoát app
Khi run app lên sẽ thấy log xuất ra như sau:
07-23 16:20:07.294 3908-3908/com.example.nguyennghia.activitylifecycle E/MainActivity: onCreate: 07-23 16:20:07.308 3908-3908/com.example.nguyennghia.activitylifecycle E/MainActivity: onStart: 07-23 16:20:07.308 3908-3908/com.example.nguyennghia.activitylifecycle E/MainActivity: onResume:
Nhấn nút back để thoát app:
07-23 16:21:25.338 3908-3908/com.example.nguyennghia.activitylifecycle E/MainActivity: onPause: 07-23 16:21:25.438 3908-3908/com.example.nguyennghia.activitylifecycle E/MainActivity: onStop: 07-23 16:21:25.438 3908-3908/com.example.nguyennghia.activitylifecycle E/MainActivity: onDestroy:
Trạng thái được chuyển từ onResume()
→ onPause()
→ onStop()
→ onDestroy()
Trường hợp 2: Start app và nhấn HOME (nút HOME của thiết bị Android)
Start app:
07-23 16:23:10.416 3908-3908/com.example.nguyennghia.activitylifecycle E/MainActivity: onCreate: 07-23 16:23:10.452 3908-3908/com.example.nguyennghia.activitylifecycle E/MainActivity: onStart: 07-23 16:23:10.452 3908-3908/com.example.nguyennghia.activitylifecycle E/MainActivity: onResume:
Nhấn HOME:
07-23 16:23:42.263 3908-3908/com.example.nguyennghia.activitylifecycle E/MainActivity: onPause: 07-23 16:23:43.023 3908-3908/com.example.nguyennghia.activitylifecycle E/MainActivity: onStop:
Vào lại app:
07-23 16:24:47.270 3908-3908/com.example.nguyennghia.activitylifecycle E/MainActivity: onRestart: 07-23 16:24:47.270 3908-3908/com.example.nguyennghia.activitylifecycle E/MainActivity: onStart: 07-23 16:24:47.270 3908-3908/com.example.nguyennghia.activitylifecycle E/MainActivity: onResume:
Và lại nhấn back để thoát app:
07-23 16:25:27.162 3908-3908/com.example.nguyennghia.activitylifecycle E/MainActivity: onPause: 07-23 16:25:27.774 3908-3908/com.example.nguyennghia.activitylifecycle E/MainActivity: onStop: 07-23 16:25:27.774 3908-3908/com.example.nguyennghia.activitylifecycle E/MainActivity: onDestroy:
Nhận thấy rằng Activity chuyển từ trạng thái onResume()
sang onPause()
và sang onStop()
khi nhấn home app. Nhưng không gọi onDestroy()
của home app, onDestroy()
của Activity tự động được gọi khi nhấn nút back hoặc gọi phương thức finish()
.
* Lưu ý: Nếu app ở trạng thái sau onStop()
quá lâu mà hệ điều hành cần bộ nhớ để chạy ứng dụng khác sẽ tiến hành thu hồi bộ nhớ và thì khi người dùng vào lại app sẽ chạy lại từ đầu từ onCreate()
→ onStart()
→ onResume()
.
Khảo sát lifecycle chuyển đổi qua lại của nhiều Activity
Ví dụ tiếp theo, lifecycle của Activity khi chuyển từ Activity này qua Activity khác.
Tạo thêm 1 Activity có tên là OtherActivity
như sau:
![](https://resources.stdio.vn/content/article/5fa767165f20ad4e0974a9f6/resources/res-1605005044-1605005044796.png)
Nhập tên Activity là OtherActivity
sau đó nhấn Next để hoàn thành.
class OtherActivity
Trước tiên log tất cả các phương thức trong lifecycle cho OtherActivity
.
Log.e(TAG, "onCreate: ");
Log.e(TAG, "onStart: ");
Log.e(TAG, "onRestart: ");
- ...
package com.example.nguyennghia.activitylifecycle; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; public class OtherActivity extends AppCompatActivity { private static final String TAG = "OtherActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_other); Log.e(TAG, "onCreate: "); } @Override protected void onStart() { super.onStart(); Log.e(TAG, "onStart: "); } @Override protected void onRestart() { super.onRestart(); Log.e(TAG, "onRestart: "); } @Override protected void onResume() { super.onResume(); Log.e(TAG, "onResume: "); } @Override protected void onPause() { super.onPause(); Log.e(TAG, "onPause: "); } @Override protected void onStop() { super.onStop(); Log.e(TAG, "onStop: "); } @Override protected void onDestroy() { super.onDestroy(); Log.e(TAG, "onDestroy: "); } }
Điều chỉnh Main Activity
Ở activity_main.xml thêm 1 button để thực hiện chuyển từ MainActivity
qua OtherActivity
.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.nguyennghia.activitylifecycle.MainActivity">
<Button
android:id="@+id/btn_nav"
android:text="Go To OtherActivity"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
Và sửa lại class MainActivity.java như sau:
package com.example.nguyennghia.activitylifecycle; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.e(TAG, "onCreate: "); findViewById(R.id.btn_nav).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { startActivity(new Intent(MainActivity.this, OtherActivity.class)); } }); } @Override protected void onStart() { super.onStart(); Log.e(TAG, "onStart: "); } @Override protected void onRestart() { super.onRestart(); Log.e(TAG, "onRestart: "); } @Override protected void onResume() { super.onResume(); Log.e(TAG, "onResume: "); } @Override protected void onPause() { super.onPause(); Log.e(TAG, "onPause: "); } @Override protected void onStop() { super.onStop(); Log.e(TAG, "onStop: "); } @Override protected void onDestroy() { super.onDestroy(); Log.e(TAG, "onDestroy: "); } }
Run app và xem log.
Khi Start app:
07-23 16:45:37.650 17690-17690/com.example.nguyennghia.activitylifecycle E/MainActivity: onCreate: 07-23 16:45:37.681 17690-17690/com.example.nguyennghia.activitylifecycle E/MainActivity: onStart: 07-23 16:45:37.681 17690-17690/com.example.nguyennghia.activitylifecycle E/MainActivity: onResume:
Khi nhấn button go to Other Activity:
07-23 16:46:40.051 18557-18557/com.example.nguyennghia.activitylifecycle E/MainActivity: onPause: 07-23 16:46:40.108 18557-18557/com.example.nguyennghia.activitylifecycle E/OtherActivity: onCreate: 07-23 16:46:40.110 18557-18557/com.example.nguyennghia.activitylifecycle E/OtherActivity: onStart: 07-23 16:46:40.111 18557-18557/com.example.nguyennghia.activitylifecycle E/OtherActivity: onResume: 07-23 16:46:40.689 18557-18557/com.example.nguyennghia.activitylifecycle E/MainActivity: onStop:
Nhận thấy MainActivity sẽ vào onPause()
sau đó OtherActivity
start Activity (onCreate()
→ onStart()
→ onResume()
) và sau đó MainActivity
mới thực sự vào onStop()
.
Tiếp tục nhấn nút back từ OtherActivity
07-23 16:49:43.623 18557-18557/com.example.nguyennghia.activitylifecycle E/OtherActivity: onPause: 07-23 16:49:43.631 18557-18557/com.example.nguyennghia.activitylifecycle E/MainActivity: onRestart: 07-23 16:49:43.631 18557-18557/com.example.nguyennghia.activitylifecycle E/MainActivity: onStart: 07-23 16:49:43.631 18557-18557/com.example.nguyennghia.activitylifecycle E/MainActivity: onResume: 07-23 16:49:43.990 18557-18557/com.example.nguyennghia.activitylifecycle E/OtherActivity: onStop: 07-23 16:49:43.991 18557-18557/com.example.nguyennghia.activitylifecycle E/OtherActivity: onDestroy:
OtherActivity
sẽ vào onPause()
sau đó MainActivity
restart lại Activity (onRestart()
→ onStart()
→ onResume()
) sau đó OtherActivity
mới vào onStop()
và đến onDestroy()
Activity.
Nhấn back từ MainActivity
07-23 16:52:15.814 18557-18557/com.example.nguyennghia.activitylifecycle E/MainActivity: onPause: 07-23 16:52:16.890 18557-18557/com.example.nguyennghia.activitylifecycle E/MainActivity: onStop: 07-23 16:52:16.890 18557-18557/com.example.nguyennghia.activitylifecycle E/MainActivity: onDestroy:
* Ngoài ra, chế độ trong Developer Options gọi là Don't Keep Activities.
![](https://resources.stdio.vn/content/article/5fa767165f20ad4e0974a9f6/resources/res-1604999682-1604999682687.png)
Kích hoạt chế độ Don't Keep Activities.
![](https://resources.stdio.vn/content/article/5fa767165f20ad4e0974a9f6/resources/res-1604999757-1604999757289.png)
Cho dù nhấn back Activity hay nhấn HOME thì Activity đó vẫn sẽ gọi onDestroy()
(từ onResume()
→ onPause()
→ onStop()
→ onDestroy()
), khi vào lại app thì sẽ gọi lại onCreate()
→ onStart()
→ onResume()
.