Programming

안드로이드의 싱글 톤과 애플리케이션 컨텍스트?

procodes 2020. 2. 28. 19:36
반응형

안드로이드의 싱글 톤과 애플리케이션 컨텍스트?


싱글 톤을 사용하고 싱글 톤 패턴을 사용하는 Android 애플리케이션의 몇 가지 예를 보았을 때이 게시물을 기억하면서 글로벌 애플리케이션 상태를 통해 공유되는 단일 인스턴스 대신 싱글 톤을 사용하는 것이 좋은지 궁금합니다. context.getApplication ()을 통해)

두 메커니즘이 갖는 장점 / 단점은 무엇입니까?

솔직히 말해서, 나는 웹 응용 프로그램 이있는이 게시물 Singleton 패턴 에서 같은 대답을 기대합니다 . 좋은 생각이 아닙니다! 안드로이드에 적용됩니다. 제가 맞습니까? DalvikVM과 다른 점은 무엇입니까?

편집 : 관련된 여러 측면에 대한 의견을 갖고 싶습니다.

  • 동기화
  • 재사용 성
  • 테스팅

Dianne Hackborn의 답변에 동의하지 않습니다. 우리는 프로젝트에서 모든 싱글 톤을 조금씩 제거하여 가볍고 작업 범위가 지정된 객체를 선호하므로 실제로 필요할 때 쉽게 다시 만들 수 있습니다.

싱글 톤은 테스트하기에 악몽이며, 게으르게 초기화 된 경우 미묘한 부작용 ( "getInstance() 한 범위에서 다른 범위 로 호출을 이동할 때 갑자기 표면화 될 수 있음 ")을 갖는 "상태 결정론"도입 할 것 입니다. 가시성은 또 다른 문제로 언급되었으며 싱글 톤 은 공유 상태에 대한 "전역"(= 랜덤) 액세스를 의미하기 때문에 동시 애플리케이션에서 올바르게 동기화되지 않으면 미묘한 버그가 발생할 수 있습니다.

나는 그것을 반 패턴으로 간주합니다. 그것은 본질적으로 전역 상태를 유지하는 데 나쁜 객체 지향 스타일입니다.

질문으로 돌아가려면 :

앱 컨텍스트는 싱글 톤 자체로 간주 될 수 있지만 프레임 워크 관리 방식이며 수명주기 , 범위 및 액세스 경로 가 잘 정의 되어 있습니다. 따라서 앱 전역 상태를 관리 해야하는 경우 다른 곳으로 가야한다고 생각합니다. 다른 무엇이든, 싱글 톤 객체가 정말로 필요하거나 싱글 톤 클래스를 다시 작성하여 현재 작업을 수행하는 작고 수명이 짧은 객체를 인스턴스화 할 수 있는지 다시 생각하십시오.


나는 싱글 톤을 매우 권장합니다. 문맥이 필요한 싱글 톤이 있다면,

MySingleton.getInstance(Context c) {
    //
    // ... needing to create ...
    sInstance = new MySingleton(c.getApplicationContext());
}

애플리케이션보다 단일 구성 요소를 선호합니다. 앱 전체의 모든 전역 상태를 유지 관리해야하는 하나의 장소가 아니라 각 개별 요소가 자체적으로 처리 할 수있는 한 곳이 아니라 훨씬 체계적이고 모듈화 된 앱을 유지하는 데 도움이되므로 응용 프로그램보다 싱글 톤을 선호합니다. 또한 Singletons가 Application.onCreate ()에서 모든 초기화를 수행하는 경로를 낮추는 대신 (요청시) 게으르게 초기화한다는 사실이 좋습니다.

싱글 톤을 사용하는 데 본질적으로 잘못된 것은 없습니다. 말이 올 바르면 올바르게 사용하십시오. Android 프레임 워크에는 실제로로드 된 리소스 및 기타 항목의 프로세스 별 캐시를 유지 관리하기 위해 많은 기능이 있습니다.

또한 간단한 응용 프로그램의 경우 멀티 스레딩은 싱글 톤에서 문제가되지 않습니다. 설계에 따라 응용 프로그램에 대한 모든 표준 콜백이 프로세스의 기본 스레드에서 전달되므로 스레드를 통해 명시 적으로 도입하지 않으면 멀티 스레딩이 발생하지 않기 때문입니다. 컨텐츠 제공자 또는 서비스 IBinder를 다른 프로세스에 공개함으로써 내재적으로.

하고있는 일에 대해 신중하게 생각하십시오. :)


보낸 사람 : 개발자> 참조-응용 프로그램

일반적으로 Application을 서브 클래 싱 할 필요는 없습니다. 대부분의 상황에서 정적 싱글 톤은보다 기능적인 방식으로 동일한 기능을 제공 할 수 있습니다. 싱글 톤에 글로벌 컨텍스트가 필요한 경우 (예 : 브로드 캐스트 수신기 등록) 싱글 톤을 처음 생성 할 때 내부적으로 Context.getApplicationContext ()를 사용하는 컨텍스트를 검색하는 함수를 검색 할 수 있습니다.


나는 같은 문제가 있었다 : Singleton 또는 하위 클래스 android.os.Application?

먼저 Singleton으로 시도했지만 어느 시점에서 내 앱이 브라우저를 호출합니다.

Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com"));

문제는 핸드셋에 메모리가 충분하지 않으면 대부분의 클래스 (싱글 톤조차)가 메모리를 확보하기 위해 청소되므로 브라우저에서 내 앱으로 돌아올 때마다 매번 충돌한다는 것입니다.

솔루션 : 필요한 데이터를 Application 클래스의 서브 클래스에 넣습니다.


응용 프로그램이 싱글 톤과 동일하지 않은 이유는 다음과 같습니다.

  1. ui 스레드에서 응용 프로그램의 메소드 (예 : onCreate)가 호출됩니다.
  2. 싱글 톤의 메소드는 모든 스레드에서 호출 될 수 있습니다.
  3. Application의 "onCreate"메소드에서 핸들러를 인스턴스화 할 수 있습니다.
  4. 싱글 톤이 none-ui 스레드에서 실행되면 핸들러를 인스턴스화 할 수 없습니다.
  5. 응용 프로그램은 응용 프로그램에서 활동의 수명주기를 관리 할 수있는 기능을 가지고 있습니다.

동시에 두 가지를 모두 고려하십시오.

  • 클래스 내부에 단일 객체를 정적 인스턴스로 사용합니다.
  • 응용 프로그램의 모든 단일 객체에 대한 단일 인스턴스를 반환하는 공통 클래스 (Context)가 있으므로 Context의 메소드 이름이 의미가 있다는 이점이 있습니다 (예 : User.getInstance () 대신 context.getLoggedinUser ()).

또한 싱글 톤 객체에 대한 액세스뿐만 아니라 context.logOffUser (), context.readSavedData () 등과 같이 전역 적으로 액세스 해야하는 일부 기능을 포함하도록 컨텍스트를 확장하는 것이 좋습니다. 그러면 외관이 의미가있을 것입니다.


그들은 실제로 동일합니다. 내가 볼 수있는 한 가지 차이점이 있습니다. Application 클래스를 사용하면 Application.onCreate ()에서 변수를 초기화하고 Application.onTerminate ()에서 변수를 삭제할 수 있습니다. 싱글 톤을 사용하면 VM 초기화 및 정적 제거에 의존해야합니다.


내 2 센트 :

내 활동이 파괴되면 일부 싱글 톤 / 정적 필드가 재설정 된 것을 알았습니다. 나는 저급 2.3 장치에서 이것을 발견했다.

제 경우는 매우 간단했습니다. 개인 파일 인 "init_done"과 activity.onCreate ()에서 호출 한 정적 메소드 "init"가 있습니다. 나는 init 메소드가 액티비티의 일부 재생성에서 스스로 다시 실행되고 있음을 알았습니다.

확인을 증명할 수는 없지만 싱글턴 / 클래스가 처음 생성 / 사용 된 시점과 관련이있을 수 있습니다. 활동이 파괴 / 재활용 될 때이 활동 만 참조하는 모든 클래스도 재활용되는 것 같습니다.

싱글 톤 인스턴스를 Application의 하위 클래스로 옮겼습니다. 응용 프로그램 인스턴스에서 액세스합니다. 그 이후로 문제를 다시는 눈치 채지 못했습니다.

이것이 누군가를 도울 수 있기를 바랍니다.


속담의 입에서 ...

앱을 개발할 때 앱에서 전 세계적으로 데이터, 컨텍스트 또는 서비스를 공유해야 할 수도 있습니다. 예를 들어 앱에 현재 로그인 한 사용자와 같은 세션 데이터가있는 경우이 정보를 노출 할 수 있습니다. Android에서이 문제를 해결하기위한 패턴은 android.app.Application 인스턴스가 모든 전역 데이터를 소유 한 다음 Application 인스턴스를 다양한 데이터 및 서비스에 대한 정적 접근자가있는 단일 항목으로 처리하는 것입니다.

Android 앱을 작성할 때는 android.app.Application 클래스의 인스턴스가 하나만 보장되므로 싱글 톤으로 취급하는 것이 안전합니다 (Google Android 팀에서 권장). 즉, 정적 getInstance () 메소드를 애플리케이션 구현에 안전하게 추가 할 수 있습니다. 이렇게 :

public class AndroidApplication extends Application {

    private static AndroidApplication sInstance;

    public static AndroidApplication getInstance(){
        return sInstance;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        sInstance = this;
    }
}

내 활동은 finish ()를 호출하고 (즉시 완료하지는 않지만 결국에는 완료 됨) Google Street Viewer를 호출합니다. Eclipse에서 디버깅 할 때 Street Viewer가 호출되면 앱에 대한 연결이 끊어지며 (전체) 응용 프로그램이 닫히고 메모리를 확보해야한다고 생각합니다 (단일 활동이 완료되면이 동작이 발생하지 않아야 함) . 그럼에도 불구하고 onSaveInstanceState ()를 통해 번들에 상태를 저장하고 스택에서 다음 활동의 onCreate () 메소드로 복원 할 수 있습니다. 정적 싱글 톤 또는 서브 클래스 링 응용 프로그램을 사용하여 응용 프로그램을 닫고 상태를 잃을 수 있습니다 (번들에 저장하지 않는 한). 제 경험에 비추어 볼 때 그들은 주 보존과 관련하여 동일합니다. Android 4.1.2 및 4.2.2에서는 연결이 끊어졌지만 4.0.7 또는 3.2.4에서는 연결이 끊어졌습니다.

참고 URL : https://stackoverflow.com/questions/3826905/singletons-vs-application-context-in-android



반응형