07 January 2017

Android: Cách thức hoạt động của Activity Stack

Cách thức hoạt động của Activity Stack
  • Khi Activity 1 run nó tạo một Stack mới (Activity 1 nó được đặt trên đỉnh stack và trở thành running activity).
  • Khi Activity 2 run tiếp đè lên Activity 1 (Activity 2 Nó được đặt trên đỉnh stack và trở thành running activity).
  • Khi Activity 2 hủy (Activity 1 nó được đặt trên đỉnh stack và trở thành running activity).
  • .....Nếu Activity 3 run tiếp đè lên Activity 2 thì (Activity 3 nó được đặt trên đỉnh stack và trỏe thành running activity)
  • ....Cứ như thế cho tới activity n+1 full ram máy

Entire Lifetime
Bảy phương thức chuyển trạng thái (Figure 3) xác định toàn bộ cuộc đời của một activity. 
Toàn bộ cuộc đời của một activity bắt đầu từ lời gọi onCreate() đầu tiên tới một lời gọi onDestroy() duy nhất cuối cùng.
Một activity thực hiện toàn bộ công việc khởi tạo trạng thái "global" tại onCreate(), trả lại tất cả các tài nguyên còn giữ tại onDestroy(). 
Visible Lifetime
visible lifetime của một activity kéo dài từ một lời gọi onStart() tới lời gọi tương ứng tới onStop().
  Trong khoảng thời gian này, người dùng thể nhìn thấy activity đó trên màn hình, tuy thể không nằm tại foreground tương tác với người dùng.
Các phương thức onStart() onStop() thể được gọi nhiều lần, khi activity chuyển giữa hai trạng thái hiện bị che đối với người dùng.
Giữa hai phương thức này, ta thể giữ các tài nguyên cần thiết cho việc hiển thị activity trên màn hình
Foreground Lifetime
foreground lifetime của một activity bắt đầu từ một lời gọi onResume() kết thúc bởi lời gọi tương ứng tới onPause().
Trong khoảng thời gian này, activity đó đứng trước mọi activity khác trên màn hình tương tác với người dùng.
Một activity thể thường xuyên chuyển qua lại giữa các trạng thái resumed paused
MethodonCreate()
Được gọi khi activity được tạo.
Đây nơi ta nên thực hiện khởi tạo tĩnh thông thườngtạo giao diện người dùng (các view), nối dữ liệu với các danh sách, v.v..
Tham số được truyền một đối tượng Bundle chứa trạng thái của activity, nếu như trạng thái đã được ghi lại.

onStart() luôn được gọi sau đó.
MethodonRestart()
Được gọi ngay trước khi activity được khởi động lại sau khi đã bị dừng (stopped).
onStart() luôn được gọi sau đó.
MethodonStart()
Được gọi ngay trước khi activity được hiện trên màn hình (visible).

Tiếp theo onResume() nếu activity lên foreground, hoặc onStop() nếu bị che.
MethodonResume()
1.Được gọi ngay trước khi activity bắt đầu tương tác với người dùng.
2.Tại thời điểm này, activity nằm trên đỉnh activity stack nhận input của người dùng.

3.Tiếp theo bao giờ cùng onPause().
MethodonPause()
1.Được gọi khi hệ thống chuẩn bị chuyển sang một activity khác.
2.Phương thức này thường dùng để ghi các thay đổi chưa được lưu, dừng hoạt hình những công việc tốn CPU khác, v.v..
3. nên làm công việc của mình thật nhanh activity tiếp theo phải đợi kết thúc thì mới resume được.
4.Tiếp theo onResume() nếu activity quay lại, hoặc onStop() nếu không còn được hiển thị đối với người dùng.

5.Activity trong trạng thái này thể bị hệ thống kill.
MethodonStop()
1.Được gọi khi activity không còn hiển thị đối với người dùng.
2.Việc này thể xảy ra khi bị hủy (destroyed), hoặc do một activity khác ( hoặc mới) đã được resume che .
3.Tiếp theo onRestart() nếu activity tương tác trở loại với người dùng, hoặc onDestroy() nếu không quay lại.

4.Hệ thống thể kill activity trong trạng thái này.
MethodonDestroy()
1.Được gọi trước khi activity bị hủy.
2.Đây lời gọi hàm cuối cùng activity nhận được.
3. thể được gọi activity đang kết thúc (hàm finish() của activity được gọi), hoặc hệ thống đang tạm thời hủy thực thể hiện tại của activity để tiết kiệm không gian bộ nhớ.
4.Ta thể phân biệt hai tình huống trên bằng cách dùng phương thức isFinishing().

5.Hệ thống thể kill activity trong trạng thái này.
Killable States – các trạng thái hệ thống kill được
Activity ở trạng thái killable thể bị hệ thống kết thúc bất cứ lúc nào sau khi phương thức trả về không thực thi thêm một dòng lệnh nào trong của activity.
Ba phương thức onPause(), onStop(), onDestroy() dẫn đến trạng thái killable.
onPause() phương thức duy nhất đảm bảo được gọi trước khi tiến trình bị hủy (killed) — onStop() onDestroy() thể không được gọi.

Do đó, ta nên dùng onPause() để lưu dữ liệu cần giữ lại (chẳng hạn các sửa đổi của người dùng). 
DEMO TỔNG HỢP

  • Ghi log phiên chạy của các method trong một Activity để ta nhìn thấy nó hoạt động onCreate, onStart ...
  • Cách lắng nghe button click hoặc set get textView xem thêm
  • Cách chuyển sang một Activity mới (Chuyển sang màn hình khác) 
  • Cách truyền nhận dữ liệu từ Activity này sang Activity kia (Truyền nhận dữ liệu màn hình a->b hoặc a<b) bằng Inten
  • Cách show dialog bằng Toast
  • Cách tạo class Constant khai báo key word sử dụng nhiều lần (Thủ thuật: Để code luôn đúng không bao giờ lập trình viên nhập sai)
Màn hình 1
activity_main.xml
Java Android 2017

<?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:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.lonely.demoapp.MainActivity">

    <TextView
        android:id="@+id/txtHello"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="10dp"
        android:text="Hello World!"
        android:textColor="#ff000d"
        android:textSize="40sp"
        android:textStyle="bold" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerInParent="true"
        android:orientation="horizontal"
        android:weightSum="2">


        <Button
            android:id="@+id/buttonCancel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="CANCEL" />

        <Button
            android:id="@+id/buttonScreen"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="SCREEN 2" />
    </LinearLayout>

</RelativeLayout>
MainActivity.java
Java Android 2017
package com.example.lonely.demoapp;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import static com.example.lonely.demoapp.R.id.buttonCancel;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private TextView txtA;
    private static final int REQUEST_CODE = 200;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Log.v("TAG", "onCreate");

        Button btnCancel = (Button) findViewById(buttonCancel);
        btnCancel.setOnClickListener(this);

        Button btnScreen = (Button) findViewById(R.id.buttonScreen);
        btnScreen.setOnClickListener(this);

        txtA = (TextView) findViewById(R.id.txtHello);
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.v("TAG", "onRestart");

    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.v("TAG", "onStart");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.v("TAG", "onResume");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.v("TAG", "onPause");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.v("TAG", "onStop");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.v("TAG", "onDestroy");
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.buttonCancel:
                Toast.makeText(MainActivity.this, "Toat Cancel", Toast.LENGTH_SHORT).show();
                txtA.setText("Click Cancel");
                break;
            case R.id.buttonScreen:
                Toast.makeText(MainActivity.this, "Toat Screen 2", Toast.LENGTH_SHORT).show();
                Intent myIntent=new Intent(MainActivity.this, MainActivity2.class);

                myIntent.putExtra("User", "Antonio");
                myIntent.putExtra("Birth", 1892);

                startActivityForResult(myIntent,REQUEST_CODE); //Chuyen du lieu qua Pags 2, don nhan du lieu tu Page 2 tra ve Page 1 hien thi

//                startActivity(myIntent); //Chi chuyen du lieu qua MainActivity, khong don nhan duoc du lieu tra ve!
                txtA.setText("Click Screen");
                break;
            default:
                break;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE) {
            if (resultCode == Constant.RESULTCODE) {
                String text = data.getStringExtra("PROFILE");
                txtA.setText(text);
            }
        }

    }
}
Màn hình 2
activity_main2.xml
Java Android 2017
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/txtPage2"
        android:text="Profile"
        android:textSize="40dp"
        android:textStyle="bold"
        android:textColor="@color/colorPrimary"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true" />

    <Button
        android:id="@+id/buttonDone"
        android:text="Done"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" />
</RelativeLayout>
MainActivity2.java
Java Android 2017
package com.example.lonely.demoapp;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

/**
 * Created by Lonely on 1/6/2017.
 */

public class MainActivity2 extends AppCompatActivity implements View.OnClickListener {

    private Button btDone;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main2);

        Log.v("TAG", "onCreate");

        Intent intent = getIntent();

        String user = intent.getStringExtra("User");
        int birth = intent.getIntExtra("Birth", 0);

        Log.d("TAG", user + " " + birth);

        btDone = (Button) findViewById(R.id.buttonDone);
        btDone.setOnClickListener((View.OnClickListener) this);
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.v("TAG", "onRestart");

    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.v("TAG", "onStart");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.v("TAG", "onResume");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.v("TAG", "onPause");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.v("TAG", "onStop");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.v("TAG", "onDestroy");
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.buttonDone:
                onDone();
                break;
            default:
                break;
        }
    }

    private void onDone() {
        Intent intent = new Intent();
        intent.putExtra("PROFILE", "Text From Profile");
        setResult(Constant.RESULTCODE, intent);
        finish();
    }

} 
Constant.java
Java Android 2017
package com.example.lonely.demoapp;

/**
 * Created by Lonely on 1/6/2017.
 */

public class Constant {
    public static String USER = "USER";
    public static  int RESULTCODE = 999;
}
Cấu trúc của project
Run demo
Tìm kiếm key TAG để hiển thị các Log 
Khi chương trình chạy lần đầu tiên sẽ chạy onCreate -> onResume
onCreate chỉ chạy một lần duy nhất
Khi bấm Cancel tôi set textView là Click Cancel và tạo Dialog Toast là Toast Cancel
Ở đây tôi hiển thị dòng Antonio 1892 thông qua Log thay cho set textView
Khi đóng màn hình 2 thứ tự gọi các method sẽ từ onPause -> onDestroy
Khi ẩn ứng dụng onPause->onStop  Hệ thống thường kill nó nếu cần bộ nhớ cho việc khác.

Khi gọi ứng dụng bị ẩn lên trạy nó sẽ bắt đầu từ onRestart-> onResume
Trên đây là toàn bộ demo basic về Activity Stack

0 nhận xét:

Post a Comment

 

BACK TO TOP

Xuống cuối trang