Vòng đời đối tượng tĩnh Android


101

Tôi đang tạo ứng dụng tìm kiếm sự kiện, chúng tôi đặt tiêu chí tìm kiếm từ một màn hình đưa vào màn hình khác, sau đó người dùng có thể chỉnh sửa tiêu chí tìm kiếm từ màn hình thứ 3 và chuyển sang màn hình thứ 4.

Để đạt được nhiệm vụ trên, tôi đang sử dụng đối tượng tĩnh ghi nhớ các giá trị xung quanh ứng dụng và tôi không cần phải làm gì thêm.

Nhưng tôi sợ nếu về vòng đời đối tượng tĩnh trong android nếu bộ nhớ thấp tìm thấy android xóa các đối tượng tĩnh ???

Vì android hỗ trợ đa tác vụ, nếu người dùng chuyển sang ứng dụng khác và khi người dùng quay lại ứng dụng bắt đầu hoạt động điên cuồng, đối tượng tĩnh có bị xóa khi nó đa tác vụ không ??? bất kỳ ý tưởng ?? và cũng đề nghị giữ đối tượng tĩnh thông qua phương pháp singleton là cách tiếp cận tốt hơn ???

Câu trả lời:


238

Hãy bắt đầu với một chút thông tin cơ bản: Điều gì sẽ xảy ra khi bạn khởi động một ứng dụng?
Hệ điều hành bắt đầu một quy trình và gán cho nó một id quy trình duy nhất và cấp phát một bảng quy trình. Một quy trình bắt đầu một phiên bản của DVM (Dalvik VM); Mỗi ứng dụng chạy bên trong một DVM.
Một DVM quản lý việc tải lớp, vòng đời phiên bản, GC, v.v.

Thời gian tồn tại của một biến tĩnh: Một biến tĩnh tồn tại khi một lớp được tải bởi JVM và chết khi lớp đó được dỡ bỏ.

Vì vậy, nếu bạn tạo một ứng dụng android và khởi tạo một biến tĩnh, nó sẽ vẫn ở trong JVM cho đến khi một trong những điều sau xảy ra:
1. lớp được dỡ bỏ
2. JVM tắt
3. quá trình chết

Lưu ý rằng giá trị của biến static sẽ vẫn tồn tại khi bạn chuyển sang một hoạt động khác của ứng dụng khác và không có điều nào trong ba điều trên xảy ra. Nếu bất kỳ điều nào trong ba điều trên xảy ra, static sẽ mất giá trị.

Bạn có thể kiểm tra điều này bằng một vài dòng mã:

  1. in tĩnh chưa được khởi tạo trong onCreate of your activity -> nên in null
  2. khởi tạo tĩnh. in nó -> giá trị sẽ không rỗng
  3. Nhấn nút quay lại và chuyển đến màn hình chính. Lưu ý: Màn hình chính là một hoạt động khác.
  4. Khởi chạy lại hoạt động của bạn -> biến tĩnh sẽ khác rỗng
  5. Hủy quy trình ứng dụng của bạn khỏi DDMS (nút dừng trong cửa sổ thiết bị).
  6. Khởi động lại hoạt động của bạn -> static sẽ có giá trị null.

Hy vọng rằng sẽ giúp.


1
Tôi muốn biết lý do tại sao tôi mất giá trị trường của mình trong đối tượng ứng dụng nếu nó không tĩnh khi tôi bắt đầu hoạt động mới, chẳng hạn như tôi khai báo trang hiện tại có thể thay đổi trong đối tượng ứng dụng và giá trị của nó luôn trở về 0 khi tôi mở hoạt động mới
Mohammed Subhi Sheikh Quroush

khi tôi gọi super.onRestoreInstanceState (saveInstanceState); Tôi mất biến ngay cả khi chúng tĩnh, vấn đề là gì?
Mohammed Subhi Sheikh Quroush 14/02/13

1
đây là một lời giải thích tốt đẹp (vì vậy không có -1) nhưng nó hơi vụn vặt: OP đã hỏi rõ ràng về "tình huống bộ nhớ thấp" (cùng lý do tại sao tôi ở đây), nơi theo như tôi biết Os có thể giết máy ảo và khởi động lại nó sau này với các thông số tương tự, và trường hợp này ( NẾU đó là một điều thật) không được đề cập ở đây ...
Rick77

1
@suitianshi Tôi nghĩ chúng ta có thể khởi tạo các trường hợp tĩnh trong Application.onCreate, bởi vì ngay cả khi ứng dụng của chúng ta ở chế độ nền và quá trình bị giết, ngay sau khi chúng ta quay lại ứng dụng của mình, lớp Ứng dụng sẽ được khởi tạo và gọi đó là các phương thức vòng đời tương ứng lần nữa! mặc dù tôi cần xác nhận về điều này, tôi tự hỏi liệu có thể có bất kỳ trường hợp nào mà phiên bản tĩnh được khởi tạo trong Application.onCreate mất giá trị không?
Sarthak Mittal

1
Điều tôi còn thiếu ở đây là lời giải thích cho "1. lớp được dỡ bỏ" - điều này sẽ xảy ra khi nào? JVM có dỡ một lớp nếu nó sắp hết bộ nhớ không?
stefln

16

Vâng, mẫu Singleton cũng dựa trên việc sử dụng các biến tĩnh, vì vậy thực sự bạn sẽ ở cùng một vị trí. Mặc dù phương pháp tiếp cận tĩnh có thể hoạt động trong hầu hết thời gian, nhưng có thể xảy ra trong một số trường hợp khi bộ nhớ đầy và một hoạt động khác chiếm ưu thế trước khi ứng dụng của bạn chuyển sang màn hình tiếp theo, quy trình hoạt động của bạn có thể bị hủy và bạn mất các giá trị tĩnh. Tuy nhiên, Android cung cấp một số tùy chọn về các giá trị liên tục giữa các trạng thái hoặc truyền chúng, chẳng hạn như:

  • sử dụng Intent, bạn có thể chuyển các tiêu chí tìm kiếm của mình từ hoạt động này sang hoạt động khác (tương tự như yêu cầu http trên web)
  • sử dụng tùy chọn ứng dụng, bạn có thể lưu các giá trị và truy xuất chúng trong hoạt động cần chúng
  • bằng cách sử dụng cơ sở dữ liệu sqlite, bạn có thể giữ chúng trong một bảng và truy xuất chúng sau
  • nếu bạn chỉ cần lưu trạng thái hoạt động để khi khởi động lại, các trường được lấp đầy bằng các giá trị đã chọn trước đó của chúng, bạn có thể triển khai phương thức hoạt động onSaveInstanceState () - lưu ý rằng điều này không được khuyến nghị giữa các hoạt động tồn tại của các trạng thái.

Bạn có thể lấy một số ví dụ mã về việc sử dụng tùy chọn, ý định và cơ sở dữ liệu sqlite bằng cách xem cây mã nguồn aegis-Shield trong mã google hoặc trong các ứng dụng Android mã nguồn mở khác.


6

Sau một số nghiên cứu, hóa ra rằng việc sử dụng Ứng dụng để lưu trữ các đĩa đơn không phải là một ý tưởng tuyệt vời, trừ khi bạn đã sẵn sàng tạo lại nó:

Không lưu trữ dữ liệu trong đối tượng ứng dụng

vì vậy, mặc dù câu trả lời được chấp nhận là đúng về mặt kỹ thuật, nhưng nó không cung cấp tất cả thông tin.

Như liên kết trên gợi ý, nếu bạn thực sự muốn gắn bó với mô hình đó, bạn cần phải sẵn sàng kiểm tra null và tạo lại dữ liệu, nếu có thể.


3

@ r1k0 ở ngay đây. Việc lưu trữ dữ liệu trong các trường tĩnh của một lớp sẽ không tự tồn tại trong quá trình ứng dụng giết và khởi động lại. Android thường xuyên giết các tiến trình (ứng dụng đang chạy) khi nó cần bộ nhớ.

Theo tài liệu Android: Trạng thái hoạt động và loại bỏ khỏi bộ nhớ ,

Hệ thống không bao giờ giết trực tiếp một hoạt động. Thay vào đó, nó giết chết quá trình mà hoạt động chạy, phá hủy không chỉ hoạt động mà còn phá hủy mọi thứ khác đang chạy trong quá trình.

Bạn có thể lưu và khôi phục trạng thái của nguyên thủy cũng như các đối tượng có thể nối tiếp và có thể phân chia bằng các phương pháp bên dưới. Chúng tự động được gọi trong vòng đời hoạt động bình thường.

protected void onSaveInstanceState(Bundle state) {}
protected void onRestoreInstanceState(Bundle savedInstanceState){}

Vì vậy, nếu bạn có một lớp chỉ có các biến tĩnh, bạn có thể lưu trạng thái của từng trường trong onSaveInstanceState () và khôi phục chúng trong onRestoreInstanceState (). Khi Android giết quá trình mà ứng dụng của bạn đang chạy, trạng thái của các biến sẽ được lưu và khi Android khôi phục ứng dụng của bạn, các giá trị sẽ được khôi phục trong bộ nhớ ở trạng thái giống như trước đó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.