Tiếp nối bài viết Android #2 - Tìm hiểu về Intent, bài viết này chúng ta sẽ tìm hiểu một thành phần cực kì quan trọng trong Android, đó là Activity.
Activity sẽ là nơi để ứng dụng hiển thị những thành phần giao diện bên trong, mỗi một ứng dụng có thể có nhiều Activity và mỗi Activity lại có những vòng đời khác nhau, việc chúng ta nắm rõ được quy luật vòng đời của nó là điều tất yếu để quản lý các thành phần giao diện của ứng dụng.
Cũng giống như con người, Activity cũng sẽ có một quá trình vòng đời từ khi được tạo ra cho đến khi bị hủy, ở mỗi phần trong một vòng đời ấy, chúng ta sẽ quyết định làm những việc gì để có thể quản lý và tối ưu được chương trình ứng dụng.
Tiền đề trước khi bước vào
Theo Android Developers, các Activity thường sẽ có liên kết lỏng lẻo với nhau, và Activity nào đang được hiển thị trên màn hình thì được xem là Activity chính và được ưu tiên trong ứng dụng. Các Activity sẽ hoạt động theo một back stack (ngăn xếp), nghĩa là khi một Activity dừng lại, nó sẽ được đẩy vào ngăn xếp để lưu trữ và được lấy ra khi những Activity thêm vào sau đó đã được đẩy ra khỏi. Có thể hiểu nôm na các Activity sẽ hoạt động theo cơ chế "Last In, First Out" (LIFO).
Cơ chế hoạt động LIFO của các activity |
Mỗi khi một Activity bị dừng hoặc được khởi tạo, ứng dụng sẽ nắm bắt các sự kiện này thông qua các phương thức được gọi là vòng đời của Activity, khi đó nó sẽ cho bạn cơ hội để thực hiện những tác vụ cụ thể sao cho phù hợp với mục đích của bạn. Chẳng hạn khi bạn khởi chạy một ứng dụng lưu trữ kho hàng thì tại phương thức khởi tạo, chúng ta phải truy database trước khi xuất dữ liệu trên giao diện, khi đóng ứng dụng đi, chúng ta đóng kết nối với database trước khi kết thúc vòng đời của Activity đó.
Bên trên là ví dụ cơ bản về tầm quan trọng của vòng đời trong Activity. Nhưng trên thực tế sẽ phát sinh khá nhiều vấn đề trong quá trình chúng ta quản lý ứng dụng. Tùy từng trường hợp cụ thể thì chúng ta sẽ thực hiện những công việc cần thiết để bảo đảm cho ứng dụng hoạt động đúng.
Bên cạnh Activity, còn có một thứ khác được gọi là Fragment (hay còn được cộng đồng AndroidDev gọi là sub-activity). Fragment cũng có vòng đời như Activity, nhưng vấn đề này mình sẽ đề cập ở một bài viết khác.
Vòng đời của Activity
Vòng đời của Activity có sơ đồ hoạt động như sau:
Vòng đời của Activity |
Để hiểu rõ hơn, chúng ta sẽ cùng đi sơ lược qua các trường hợp:
Trường hợp 1: Khởi chạy một Activity mới
Như ở bài trước về Intent, chúng ta đã nắm được cách khởi chạy một Activity mới, bạn có thể tìm hiểu thêm tại đây!Trước tiên, mình sẽ tạo thêm một Activity và đặt tên là SecondActivity.
Sau đó mình truy xuất các phương thức vòng đời bên trong cả 2 Activity và log lại bên trong mỗi phương thức. Bên trong MainActivity, mình sẽ thêm một button để khởi chạy SecondActivity:
/* MainActivity.java */ public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toast.makeText(this, "MainActivity: onCreate()", Toast.LENGTH_LONG).show(); // Ánh xạ ButtonView Button btn = findViewById(R.id.btn); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(MainActivity.this, SecondActivity.class)); } }); } @Override protected void onStart() { super.onStart(); Toast.makeText(this, "MainActivity: onStart()", Toast.LENGTH_LONG).show(); } @Override protected void onResume() { super.onResume(); Toast.makeText(this, "MainActivity: onResume()", Toast.LENGTH_LONG).show(); } @Override protected void onRestart() { super.onRestart(); Toast.makeText(this, "MainActivity: onRestart()", Toast.LENGTH_LONG).show(); } @Override protected void onPause() { super.onPause(); Toast.makeText(this, "MainActivity: onPause()", Toast.LENGTH_LONG).show(); } @Override protected void onStop() { super.onStop(); Toast.makeText(this, "MainActivity: onStop()", Toast.LENGTH_LONG).show(); } @Override protected void onDestroy() { super.onDestroy(); Toast.makeText(this, "MainActivity: onDestroy()", Toast.LENGTH_LONG).show(); } }
/* SecondActivity.java */ public class SecondActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); Toast.makeText(this, "SecondActivity: onCreate()", Toast.LENGTH_LONG).show(); } @Override protected void onStart() { super.onStart(); Toast.makeText(this, "SecondActivity: onStart()", Toast.LENGTH_LONG).show(); } @Override protected void onResume() { super.onResume(); Toast.makeText(this, "SecondActivity: onResume()", Toast.LENGTH_LONG).show(); } @Override protected void onRestart() { super.onRestart(); Toast.makeText(this, "SecondActivity: onRestart()", Toast.LENGTH_LONG).show(); } @Override protected void onPause() { super.onPause(); Toast.makeText(this, "SecondActivity: onPause()", Toast.LENGTH_LONG).show(); } @Override protected void onStop() { super.onStop(); Toast.makeText(this, "SecondActivity: onStop()", Toast.LENGTH_LONG).show(); } @Override protected void onDestroy() { super.onDestroy(); Toast.makeText(this, "SecondActivity: onDestroy()", Toast.LENGTH_LONG).show(); } }Khởi chạy ứng dụng, MainActivity sẽ được khởi tạo. Khi đó, onCreate() sẽ được gọi đầu tiên và đứng lại tại onResume(), chứng tỏ MainActivity đang được chạy trên màn hình.
Sau đó chúng ta nhấn vào button để khởi chạy SecondActivity, khi đó onPause() của MainActivity sẽ được gọi và onStop() được truy xuất sau khi SecondActivity đã được khởi chạy thành công.
Tiếp tục nhấn nút Back, khi đó các Activity sẽ tuân theo cơ chế LIFO, do đó SecondActivity sẽ bị hủy (onDestroy()) và MainActivity được khởi chạy trở lại.
Trường hợp 2: Khởi chạy Dialog
Tính chất của Dialog là khi được khởi chạy, nó sẽ đè lên Activity khác nhưng vẫn còn nhìn thấy Activity đó.
Để kiểm tra trường hợp này, bạn có thể cài đặt SecondActivity thành dialog trong file manifest như sau:
<activity android:name=".SecondActivity" android:theme="@style/Theme.AppCompat.Dialog"></activity>Tương tự như trường hợp 1, MainActivity được khởi tạo.
Lý do là vì chúng ta vẫn còn nhìn thấy MainActivity ở phía sau mà không phải bị che khuất đi như trong trường hợp 1.
Trường hợp 3: Xoay điện thoại
Khi xoay điện thoại, phương thức onDestroy() sẽ được gọi ra để hủy hoàn toàn giao diện của Activity. Sau đó phương thức onCreate() được gọi lại để thiết lập lại giao diện cho phù hợp với giao diện nằm ngang.
Kết luận
Trước khi kết thúc bài viết, một vấn đề được đặt ra là làm thế nào để có thể giữ được trạng thái của Activity sau khi chúng ta xoay màn hình?
Giả sử trong Activity của bạn có một EditText và bạn nhập một vài từ vào đó, sau đó xoay màn hình thì tất cả những từ bạn vừa nhập đều sẽ bị mất vì onDestroy() sẽ được gọi và onCeate() sẽ được khởi tạo trở lại.
Điều này mình sẽ để dành cho các bạn!
Thanh Dương
Android #3 - Vòng đời của Activity (Activity life-cycle) và tại sao chúng ta cần phải biết nó?
Reviewed by Duong-Tran Thanh
on
9/18/2019 03:08:00 CH
Rating:
Không có bình luận nào!