Các hoạt động phá hủy Android, các quá trình tiêu diệt


117

Xin chào, tôi đang tự hỏi cách Android quản lý bộ nhớ và tôi không thể tìm thấy câu trả lời chính xác ở bất kỳ đâu. Giả sử tôi có một ứng dụng có 5 hoạt động trên ngăn xếp hoạt động hiện tại (4 bị dừng và 1 được tiếp tục lại), không có dịch vụ nào được kết nối. Tôi nhấn nút HOME để tất cả các hoạt động của tôi bị dừng lại. Tôi bắt đầu một số ứng dụng tiêu tốn bộ nhớ khác và bộ nhớ thiết bị tổng thể đang bắt đầu thấp. Và câu hỏi là

... Điều gì sẽ xảy ra với ứng dụng của tôi?

  1. Hệ thống có thể chỉ phá hủy một hoặc một số hoạt động của tôi để khôi phục bộ nhớ không?
  2. Hệ thống có giết toàn bộ quá trình ứng dụng của tôi không? Tất cả các hoạt động sẽ bị phá hủy một cách độc đáo?
  3. Điều gì sẽ xảy ra khi tôi quay lại ứng dụng của mình khi nó đã hoàn toàn bị hủy? Nó sẽ bắt đầu từ việc ăn xin (như lần bắt đầu đầu tiên) hay nó sẽ cố gắng khôi phục các hoạt động về trạng thái trước đó / nếu có - nó chỉ là hoạt động ở trên cùng của ngăn xếp hay tất cả chúng?

CẬP NHẬT:

Trước khi hỏi câu hỏi này, tôi đã xem Vòng đời hoạt động một vài lần nhưng nó không có câu trả lời cho câu hỏi của tôi. Tôi đã thực hiện một số bài kiểm tra và tôi có một số câu trả lời. "Quá trình dừng" trong DDMS là một manh mối để kiểm tra.

Tôi chưa kiểm tra câu trả lời cho câu hỏi 1, nhưng như hướng dẫn cho biết:

Nếu một hoạt động bị tạm dừng hoặc dừng, hệ thống có thể loại bỏ hoạt động đó khỏi bộ nhớ bằng cách yêu cầu nó kết thúc hoặc đơn giản là giết quá trình của nó.

Có vẻ như một hoặc nhiều hoạt động có thể bị phá hủy nhẹ nhàng (với phương pháp onDestroy) mà không giết chết quá trình. Bạn sẽ chỉ nhận được (onCreate + gói) khi quay lại với chúng.

Câu trả lời câu hỏi 2:

ĐÚNG. Nói chung hệ thống giết toàn bộ quá trình, điều này có nghĩa là tất cả dữ liệu bao gồm các hoạt động và trường tĩnh đều bị phá hủy. Điều này KHÔNG được thực hiện tốt - bạn sẽ không nhận được onDestroy hoặc finialize () cho bất kỳ hoạt động bị tạm dừng / dừng nào của mình. Đây là lý do tại sao saveInstanceState () được gọi ngay trước phương thức onPause. onPause về cơ bản là phương pháp cuối cùng mà bạn nên lưu một cái gì đó vì sau phương pháp này, bạn sẽ không bao giờ thấy onStop hoặc onDestroy. Hệ thống chỉ có thể giết quá trình phá hủy tất cả các đối tượng của bạn bất cứ thứ gì chúng giữ và bất cứ điều gì chúng đang làm.

Câu trả lời câu hỏi 3:

Điều gì sẽ xảy ra khi bạn quay lại một ứng dụng đã bị hủy?

  • Trước Android 2.2 - ứng dụng sẽ bắt đầu từ khi bắt đầu, với hoạt động của trình khởi chạy.
  • Bắt đầu từ 2.2 - hệ thống sẽ khôi phục trạng thái ứng dụng trước đó. Nó có nghĩa là gì? Có nghĩa là hoạt động hiển thị gần đây nhất sẽ được tạo lại (onCreate + gói). Điều gì sẽ xảy ra với ngăn xếp hoạt động? Stack vẫn ổn nhưng mọi hoạt động trên đó đã chết. Mỗi người trong số họ sẽ được tạo lại (onCreate + gói) khi bạn quay lại nó bằng nút quay lại. Còn một điều nữa về điều đó:

Thông thường, hệ thống sẽ xóa một tác vụ (xóa tất cả các hoạt động khỏi ngăn xếp phía trên hoạt động gốc) trong một số tình huống nhất định khi người dùng chọn lại tác vụ đó từ màn hình chính. Thông thường, điều này được thực hiện nếu người dùng không truy cập tác vụ trong một khoảng thời gian nhất định, chẳng hạn như 30 phút.

Phần kết luận?

  1. Đừng nghĩ rằng việc xử lý các vấn đề xoay vòng hoạt động có thể được giải quyết bằng android: configChanges = "direction". Khi bạn làm điều đó, bạn sẽ gặp phải nhiều vấn đề khác mà bạn thậm chí không nhận thức được.
  2. Kiểm tra ứng dụng của bạn với DDMS - Nút dừng quá trình. Xem này
  3. Hãy cẩn thận khi sử dụng các biến tĩnh. Đừng nghĩ rằng khi bạn khởi tạo chúng trong hoạt động 1 - bạn sẽ khởi tạo chúng trong hoạt động 2. Nơi an toàn duy nhất để khởi tạo tĩnh toàn cục sẽ là lớp Ứng dụng.
  4. Hãy nhớ rằng bạn có thể không bao giờ thấy onStop hoặc onDestroy. Đóng tệp / cơ sở dữ liệu, dừng trình tải xuống trong Tạm dừng. Khi bạn muốn ứng dụng làm điều gì đó trong BG - hãy sử dụng Dịch vụ nền trước.

Đó sẽ là nó ... Hy vọng tôi đã giúp với bài luận của tôi :)


Đối với giả định của bạn, 5 hoạt động đó đến từ cùng một ứng dụng hay một số ứng dụng khác nhau?
câm

1
"Tôi có một ứng dụng với 5 hoạt động trên ngăn xếp hoạt động hiện tại" Tất nhiên chúng đều là từ ứng dụng quy trình giống nhau của tôi.
Đánh dấu

4
Cảm ơn bạn, đây chính xác là câu hỏi của tôi ... Câu hỏi của bạn và câu trả lời đã giúp tôi khá nhiều.
craigrs84


@Mark: Vấn đề này hiện đã được giải quyết chưa? Làm thế nào nếu nó là?
Ameer Moaaviah,

Câu trả lời:


30

Trước tiên, hãy xem cái này:

img1

onPause () Được gọi khi hệ thống sắp bắt đầu tiếp tục hoạt động trước đó. Điều này thường được sử dụng để cam kết các thay đổi chưa được lưu đối với dữ liệu liên tục, dừng hoạt ảnh và những thứ khác có thể tiêu tốn CPU, v.v. Việc triển khai phương thức này phải rất nhanh chóng vì hoạt động tiếp theo sẽ không được tiếp tục cho đến khi phương thức này trở lại. Tiếp theo là onResume () nếu hoạt động quay trở lại phía trước hoặc onStop () nếu nó ẩn với người dùng.

onStop () Được gọi khi hoạt động không còn hiển thị với người dùng vì một hoạt động khác đã được tiếp tục và đang che hoạt động này. Điều này có thể xảy ra vì một hoạt động mới đang được bắt đầu, một hoạt động hiện có đang được đưa ra trước hoạt động này hoặc hoạt động này đang bị phá hủy. Tiếp theo là onRestart () nếu hoạt động này quay trở lại để tương tác với người dùng hoặc onDestroy () nếu hoạt động này ngừng hoạt động.

Vì vậy, khi bạn nhấn nút "HOME" trên thiết bị của mình, hoạt động nền trước hiện tại của bạn sẽ được đưa lên onPause()sau đó onStop(), 4 hoạt động còn lại sẽ vẫnonStop()

Theo Tài liệu của Google:

  • Nếu một hoạt động ở nền trước của màn hình (ở đầu ngăn xếp), nó đang hoạt động hoặc đang chạy.
  • Nếu một hoạt động bị mất tiêu điểm nhưng vẫn hiển thị (nghĩa là, một hoạt động không có kích thước đầy đủ hoặc minh bạch mới có tiêu điểm ở đầu hoạt động của bạn), hoạt động đó sẽ bị tạm dừng. Một hoạt động bị tạm dừng hoàn toàn tồn tại (nó duy trì tất cả thông tin trạng thái và thành viên và vẫn được gắn với trình quản lý cửa sổ), nhưng có thể bị hệ thống giết chết trong tình huống bộ nhớ cực thấp.
  • Nếu một hoạt động bị che khuất hoàn toàn bởi một hoạt động khác, nó sẽ bị dừng lại. Nó vẫn giữ tất cả thông tin thành viên và trạng thái, tuy nhiên, nó không còn hiển thị cho người dùng nữa nên cửa sổ của nó bị ẩn đi và nó thường bị hệ thống khai tử khi cần bộ nhớ ở nơi khác.
  • Nếu một hoạt động bị tạm dừng hoặc dừng, hệ thống có thể loại bỏ hoạt động đó khỏi bộ nhớ bằng cách yêu cầu nó kết thúc hoặc đơn giản là giết quá trình của nó. Khi nó được hiển thị lại cho người dùng, nó phải được khởi động lại hoàn toàn và khôi phục về trạng thái trước đó.

Và, đối với vòng đời của quy trình:

Vòng đời của quy trình 3. Hoạt động nền (một hoạt động không hiển thị với người dùng và đã bị tạm dừng) không còn quan trọng nữa, vì vậy hệ thống có thể kết thúc quá trình của nó một cách an toàn để lấy lại bộ nhớ cho các quy trình nền trước hoặc hiển thị khác. Nếu quy trình của nó cần phải bị hủy, khi người dùng điều hướng trở lại hoạt động (làm cho nó hiển thị lại trên màn hình), phương thức onCreate (Bundle) của nó sẽ được gọi với SaveInstanceState mà nó đã cung cấp trước đó trong onSaveInstanceState (Bundle) để nó có thể tự khởi động lại ở trạng thái giống như lần cuối người dùng rời khỏi nó.

Tất cả các trích dẫn trên đều đến từ: Tham khảo nhà phát triển Android: Hoạt động

Người ta xác nhận rằng hệ thống có thể phá hủy các hoạt động không hoạt động và tái chế ký ức khi bạn khởi chạy một số ứng dụng tiêu tốn bộ nhớ. Và bạn có thể thực hiện như: isFinishing()trong hoạt động của bạn và sau đó sử dụng nút "giết" trong DDMS để phát hiện hoạt động nào của bạn đang bị hệ thống bỏ qua. Nhưng tôi đoán hệ thống sẽ phá hủy cái cũ nhất trước. Tuy nhiên, việc giữ lại các hoạt động khác cũng chẳng ích gì khi "Hoạt động Khởi động" đã được tái chế.

CẬP NHẬT

Đây là một số ý kiến ​​tôi tìm thấy từ đây :

Trạng thái dừng

Khi một hoạt động không hiển thị nhưng vẫn còn trong bộ nhớ, chúng tôi nói rằng nó đang ở trạng thái dừng. Hoạt động đã dừng có thể được đưa trở lại trước để trở thành Hoạt động đang chạy trở lại. Hoặc, nó có thể bị phá hủy và xóa khỏi bộ nhớ.

Hệ thống giữ cho các hoạt động xung quanh ở trạng thái đã dừng vì có khả năng người dùng vẫn muốn quay lại các hoạt động đó sớm hơn và việc khởi động lại hoạt động đã dừng rẻ hơn nhiều so với việc bắt đầu một hoạt động từ đầu. Đó là vì chúng ta đã có tất cả các đối tượng được tải trong bộ nhớ và chỉ cần đưa tất cả lên nền trước.

Các hoạt động bị dừng có thể bị xóa khỏi bộ nhớ bất kỳ lúc nào.


4
Tài liệu khá khó hiểu về vấn đề này, tuy nhiên chỉ có thể giết toàn bộ quy trình, không phải các thành phần riêng lẻ (hoạt động, dịch vụ, v.v.). Xem: stackoverflow.com/questions/7536988/…
greg7gkb

Câu hỏi này cần được cập nhật với các thông tin trong liên kết của @ bình luận greg7gkb, nó gây hiểu lầm
Luke De Feo

1

Hệ thống có thể chỉ phá hủy một hoặc một số hoạt động của tôi để khôi phục bộ nhớ không?

Đúng. Android sẽ giết các hoạt động đang chạy trong nền khi cần bộ nhớ. Giết một hoặc tất cả có thể phụ thuộc vào một số điều kiện. Đối với một phiên bản bị tạm dừng hoặc bị dừng có thể khiến android giết chết một hoạt động hoặc chính quá trình. Tại đây trong Vòng đời hoạt động, bạn có thể nhận được các điểm dưới đây. Tôi khuyên bạn nên xem qua trang đó hoàn toàn. Nó chắc chắn sẽ giải tỏa những nghi ngờ của bạn.

Nếu một hoạt động bị mất tiêu điểm nhưng vẫn hiển thị (nghĩa là, một hoạt động không có kích thước đầy đủ hoặc minh bạch mới có tiêu điểm ở đầu hoạt động của bạn), hoạt động đó sẽ bị tạm dừng. Một hoạt động bị tạm dừng hoàn toàn tồn tại (nó duy trì tất cả thông tin trạng thái và thành viên và vẫn được gắn với trình quản lý cửa sổ), nhưng có thể bị hệ thống giết chết trong tình huống bộ nhớ cực thấp.

Nếu một hoạt động bị che khuất hoàn toàn bởi một hoạt động khác, nó sẽ bị dừng lại. Nó vẫn giữ tất cả thông tin thành viên và trạng thái, tuy nhiên, nó không còn hiển thị cho người dùng nữa nên cửa sổ của nó bị ẩn đi và nó thường bị hệ thống khai tử khi cần bộ nhớ ở nơi khác.

Nếu một hoạt động bị tạm dừng hoặc dừng, hệ thống có thể loại bỏ hoạt động đó khỏi bộ nhớ bằng cách yêu cầu nó kết thúc hoặc đơn giản là giết quá trình của nó. Khi nó được hiển thị lại cho người dùng, nó phải được khởi động lại hoàn toàn và khôi phục về trạng thái trước đó.


Hệ thống có giết toàn bộ quá trình ứng dụng của tôi không? Tất cả các hoạt động sẽ bị phá hủy một cách độc đáo?

Hoạt động liên quan đến một cá nhân trong khi quá trình liên quan đến nhóm hoạt động. Nhìn vào điểm thứ ba ở trên một lần nữa nó giết chết quá trình như đã đề cập.


Điều gì sẽ xảy ra khi tôi quay lại ứng dụng của mình khi nó đã hoàn toàn bị hủy?

Nó tương tự như khởi động lại. Một lần nữa, điểm thứ ba sẽ cung cấp cho bạn một số câu trả lời nhưWhen it is displayed again to the user, it must be completely restarted and restored to its previous state

Nhận thêm một số thông tin về các nội dung liên quan đến bộ nhớ tại đây .

Chỉnh sửa:
Tất cả các hoạt động trong một ứng dụng chạy trong một quy trình duy nhất. Vì vậy, khi một tiến trình bị giết, tất cả các hoạt động không có vấn đề 5 hay 10 sẽ bị giết, tức là được khởi động lại. Khởi động lại sẽ khiến ứng dụng của bạn khởi động lại từ đầu mà không có trạng thái nào được lưu.


2
Tôi đã xem Vòng đời hoạt động ít nhất 5 lần nhưng nó không trả lời câu hỏi của tôi. Những gì bạn nói sẽ có nghĩa là khi quy trình ứng dụng của tôi bị hủy - khi tôi quay lại ứng dụng, nó sẽ được khôi phục về trạng thái trước đó. Vì vậy, khi tôi có 5 hoạt động bị dừng .. tất cả chúng đều chết (onDestroy đã gọi) khi tiến trình bị giết? Khi tôi quay lại ứng dụng của mình, tất cả các hoạt động đã được khôi phục (onCreate + gói) hay chỉ một hoạt động ở đầu ngăn xếp (hiển thị với người dùng)?
Đánh dấu

1
Tất cả các hoạt động trong một ứng dụng chạy trong một quy trình duy nhất. Vì vậy, khi một tiến trình bị giết, tất cả các hoạt động không có vấn đề 5 hay 10 sẽ bị giết, tức là được khởi động lại. Khởi động lại sẽ khiến ứng dụng của bạn bắt đầu lại từ đầu không có trạng thái nào được lưu ..
Vinay

1
Gần như đúng, nhưng không phải đối với 2.2 trở lên. Xem CẬP NHẬT của tôi ở đầu trang.
Đánh dấu

1
Không, điều này không đúng và chưa bao giờ đúng. Cũng rất lúng túng dựa trên các tài liệu, nhưng xem: stackoverflow.com/questions/7536988/...
greg7gkb

2
@JJPA Android không thể phá hủy các Hoạt động đơn lẻ để lấy lại bộ nhớ, nó chỉ phá hủy các quy trình. Hãy xem câu trả lời này của Dianne Hackbor, thành viên cốt lõi của nhóm Android tham gia vào quá trình triển khai "kẻ giết người hết bộ nhớ": stackoverflow.com/a/7576275/1290264 .
bcorso
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.