+4

Khi nào cần lưu trạng thái trong Activity

Giới thiệu

    protected void onCreate(Bundle savedInstanceState) {
        //
    }

Chắc hẳn có nhiều bạn mới lập trình Android thường không để ý đến biên savedInstanceState trong hàm onCreat() này.

Vấn đề

Vấn đề mình muốn chia sẻ hôm nay là việc truyền thông qua phương thức onCreate() và onRestoreInstanceState() .

Mình có một đối tượng view sau

    private ProgressDialog progressDialog;

Mình khởi tạo nó trong 1 asyntask khác

        public void onPreExecute() {
            progressDialog = new ProgressDialog(LoginActivity.this);
            progressDialog.setMessage(getResources().getString(R.string.loading));
            progressDialog.setCancelable(false);
            progressDialog.show();
    }

và kết thúc nó khi nó hoạt động xong

        public void onPostExecute(String s) {
            progressDialog.dismiss();
        }

Câu chuyện ở đây là khi dialog đang hiển thị. Tức là hàm onBackGround() đang hoạt động, tôi lập tức xoay màn hình và cái tôi nhân được đó là app crash.

Nguyên nhân

Điều này có thể được lý giải như sau. Khi xoay màn hình, activity sẽ khởi động lại view và do đó progressdialog của tôi đang hiển thị nhưng lại bị null dẫn đến crash app.

Cách giải quyết

Bạn cần override phương thức onSaveInstanceState(Bundle savedInstanceState) và ghi lại những giá trị mà bạn muốn để thay đổi thông tin trong Bundle như sau:

        protected void onSaveInstanceState(Bundle outState) {
            super.onSaveInstanceState(outState);
            outState.putBoolean(Const.CONTENT_LOADING, progressDialog.isShowing());
        }

Về bản chất thì Bundle là một cách để ta lưu trữ một NVP ("Name-Value pair"), nó sẽ được truyền thông qua phương thức onCreate() và onRestoreInstanceState() - Đây là nơi bạn có thể lấy ra những giá trị mà bạn đã lưu, bằng cách như sau:

        protected void onRestoreInstanceState(Bundle savedInstanceState) {
            super.onRestoreInstanceState(savedInstanceState);
            if(savedInstanceState.getBoolean(Const.CONTENT_LOADING)) {
                    progressDialog.setMessage(getResources().getString(R.string.loading));
            progressDialog.show();
        }
    }

Thường thì chúng ta dùng kỹ thuật này để lưu trữ những giá trị trong ứng dụng như những sự lựa chọn, text chưa được save, v.v...

Đọc thêm tại reference: click here


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí