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.