Android 정적 개체 수명주기


101

이벤트 검색 애플리케이션을 만들고 있는데, 한 화면에서 검색 기준을 설정하고 다른 화면에 입력하면 사용자가 3 번째 화면에서 검색 기준을 편집하고 4 번째 화면으로 이동할 수 있습니다.

위의 작업을 수행하기 위해 응용 프로그램 주변의 값을 기억하는 정적 개체를 사용하고 있으며 추가 작업을 수행 할 필요가 없습니다.

하지만 메모리가 부족한 경우 안드로이드의 정적 개체 수명주기에 대해 두려워합니다. 안드로이드 정적 개체 삭제 ???

안드로이드가 멀티 태스킹을 지원하기 때문에 사용자가 다른 애플리케이션으로 전환하고 애플리케이션이 돌아 왔을 때 애플리케이션이 미친 짓을 시작하면 멀티 태스킹시 정적 객체가 제거됩니까? 어떤 생각? 또한 singleton 방법을 통해 정적 객체를 유지하는 것이 더 나은 접근 방식을 제안합니다 ???

답변:


238

약간의 배경 지식부터 시작하겠습니다. 응용 프로그램을 시작하면 어떻게됩니까?
OS는 프로세스를 시작하고 고유 한 프로세스 ID를 할당하고 프로세스 테이블을 할당합니다. 프로세스는 DVM (Dalvik VM)의 인스턴스를 시작합니다. 각 애플리케이션은 DVM 내에서 실행됩니다.
DVM은 클래스 로딩 언로드, 인스턴스 수명주기, GC 등을 관리합니다.

정적 변수의 수명 : 정적 변수는 JVM에 의해 클래스가로드 될 때 존재하고 클래스가 언로드되면 죽습니다.

따라서 Android 애플리케이션을 만들고 정적 변수를 초기화하면 다음 중 하나가 발생할 때까지 JVM에 남아 있습니다.
1. 클래스가 언로드됩니다
. 2. JVM이 종료됩니다.
3. 프로세스가 종료됩니다.

정적 변수의 값은 다른 애플리케이션의 다른 활동으로 전환 할 때 유지되며 위의 세 가지 중 어느 것도 발생하지 않습니다. 위의 세 가지 중 하나가 발생하면 정적 값이 손실됩니다.

몇 줄의 코드로이를 테스트 할 수 있습니다.

  1. 활동의 onCreate에서 초기화되지 않은 정적을 인쇄-> null을 인쇄해야합니다.
  2. 정적을 초기화하십시오. 인쇄-> 값은 null이 아닙니다.
  3. 뒤로 버튼을 누르고 홈 화면으로 이동합니다. 참고 : 홈 화면은 또 다른 활동입니다.
  4. 활동을 다시 시작하십시오-> 정적 변수가 null이 아닙니다.
  5. DDMS에서 애플리케이션 프로세스를 종료합니다 (장치 창에서 중지 버튼).
  6. 활동을 다시 시작하십시오-> 정적은 null 값을 갖습니다.

도움이 되었기를 바랍니다.


1
새 활동을 시작할 때 정적이 아닌 경우 응용 프로그램 개체에서 내 필드 값을 잃는 이유를 알고 싶습니다. 예를 들어 응용 프로그램 개체에서 변수 현재 페이지를 선언하고 새 활동을 열 때 해당 값이 항상 0으로 돌아갑니다
— Mohammed Subhi Sheikh Quroush

super.onRestoreInstanceState (savedInstanceState); 변수가 정적 인 경우에도 손실됩니다. 문제는 무엇입니까?
— Mohammed Subhi Sheikh Quroush 2013

1
이것은 좋은 설명 (그래서 -1이 아님)이지만 약간 중요하지 않습니다. OP는 "메모리 부족 상황"에 대해 명시 적으로 질문했습니다 (제가 여기있는 이유와 같은 이유). 내가 아는 한 OS가 VM을 죽일 수 있고 (동일한 매개 변수를 사용하여 나중에 다시 시작하고이 경우 경우 그것은 진짜입니다) ... 여기에 포함되지 않습니다
— Rick77

1
@suitianshi Application.onCreate에서 정적 인스턴스를 초기화 할 수 있다고 생각합니다. 왜냐하면 앱이 백그라운드로 들어가 프로세스가 종료 되더라도 앱으로 돌아가 자마자 Application 클래스가 인스턴스화되고 해당 수명주기 메서드를 호출하기 때문입니다. 다시! 이에 대한 확인이 필요하지만 Application.onCreate에서 초기화 된 정적 인스턴스가 값을 잃는 시나리오가 있는지 궁금합니다.
— Sarthak Mittal

1
여기서 내가 놓친 것은 "1. 클래스가 언로드되었습니다"에 대한 설명입니다. 언제 이런 일이 발생합니까? JVM이 메모리가 부족한 경우 클래스를 언로드합니까?
— stoefln

16

음, Singleton 패턴은 정적 변수 사용을 기반으로하므로 실제로 동일한 위치에 있습니다. 정적 접근 방식이 대부분의 경우 작동 할 수 있지만, 애플리케이션이 다음 화면으로 이동하기 전에 메모리가 가득 차고 다른 활동이 포 그라운드를 차지하는 경우에 활동의 프로세스가 종료되고 정적 값이 손실 될 수 있습니다. 그러나 Android는 다음과 같이 상태간에 값을 유지하거나 전송하는 몇 가지 옵션을 제공합니다.

  • 인 텐트를 사용하면 활동에서 활동으로 검색 기준을 전달할 수 있습니다 (웹 http 요청과 유사).
  • 응용 프로그램 환경 설정을 사용하여 값을 저장하고 필요한 활동에서 검색 할 수 있습니다.
  • sqlite 데이터베이스를 사용하여 테이블에 유지하고 나중에 검색 할 수 있습니다.
  • 다시 시작할 때 필드가 이전에 선택한 값으로 채워지도록 활동 상태를 저장해야하는 경우 onSaveInstanceState () 활동 메서드를 구현할 수 있습니다.이 방법은 상태의 활동 간 지속성에는 권장되지 않습니다.

Google 코드 또는 기타 오픈 소스 Android 애플리케이션에서 aegis-shield 소스 코드 트리 를 살펴보면 기본 설정, 인 텐트 및 sqlite 데이터베이스 사용에 대한 코드 예제를 얻을 수 있습니다 .


6

몇 가지 연구 끝에 Application을 사용하여 단일 항목을 저장하는 것은 다시 만들 준비가되지 않은 한 그다지 좋은 생각이 아닙니다.

응용 프로그램 개체에 데이터를 저장하지 마십시오

그래서 받아 들여진 대답은 은 기술적으로 정확하지만 모든 정보를 제공하지는 않습니다.

위의 링크에서 알 수 있듯이 실제로 해당 모델을 고수하려면 가능한 경우 null을 확인하고 데이터를 다시 생성 할 준비가되어 있어야합니다.


3

@ r1k0이 바로 여기입니다. 클래스의 정적 필드에 데이터를 저장하면 애플리케이션 프로세스가 종료되고 다시 시작되는 동안 자체적으로 유지되지 않습니다. Android는 메모리가 필요할 때 일상적으로 프로세스 (앱 실행)를 종료합니다.

Android 문서에 따라 : Activity state and ejection from memory ,

시스템은 활동을 직접 종료하지 않습니다. 대신 활동이 실행되는 프로세스를 종료하여 활동뿐만 아니라 프로세스에서 실행중인 다른 모든 항목도 파괴합니다.

아래 방법을 사용하여 직렬화 가능 및 Parcelable 객체뿐만 아니라 원시 상태의 상태를 저장하고 복원 할 수 있습니다. 정상적인 활동 수명주기 동안 자동으로 호출됩니다.

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

따라서 정적 변수 만있는 클래스가있는 경우 각 필드의 상태를 onSaveInstanceState ()에 저장하고 onRestoreInstanceState ()에서 복원 할 수 있습니다. Android가 앱이 실행중인 프로세스를 종료하면 변수 상태가 저장되고 Android가 앱을 복원 할 때 값이 이전과 동일한 상태로 메모리에 복원됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.