programing

싱글톤과Android의 애플리케이션 컨텍스트

copysource 2022. 8. 27. 23:44
반응형

싱글톤과Android의 애플리케이션 컨텍스트

싱글톤 사용에 관한 가지 문제점이나 싱글톤 패턴을 사용한 안드로이드 어플리케이션의 몇 가지 예를 본 이 있는 이 투고를 상기하면, 글로벌 어플리케이션 상태(Android.os 하위 분류)에서 공유되는 싱글 인스턴스 대신 싱글톤을 사용하는 것이 좋은 생각인지 궁금합니다.context.get Application()을 통해 어플리케이션을 취득합니다.

두 메커니즘 모두 어떤 이점/장점이 있습니까?

솔직히 이 포스트싱글턴 패턴에서 웹 어플리케이션과 같은 답변을 기대하고 있습니다.Not a good idea!는 Android에 적용되어 있습니다.내가 맞나요?달리 DalvikVM의 차이점은 무엇입니까?

편집: 관련된 몇 가지 측면에 대해 의견을 듣고 싶습니다.

  • 동기
  • 재사용 가능성
  • 테스트

나는 Dianne Hackborn의 대답에 매우 동의하지 않는다.실제로 필요할 때 쉽게 재현할 수 있는 가볍고 작업 범위 내의 오브젝트를 위해 프로젝트에서 모든 싱글톤을 조금씩 제거하고 있습니다.

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

저는 이것이 반패턴이라고 생각합니다.이것은 기본적으로 글로벌 상태를 유지하는 것과 같은 나쁜 객체 지향 스타일입니다.

질문으로 돌아가려면:

앱 콘텍스트 자체는 싱글톤으로 간주할 수 있지만 프레임워크로 관리되며 라이프 사이클, 범위 및 액세스 경로가 잘 정의되어 있습니다.따라서 app-global 상태를 관리할 필요가 있다면 다른 곳 말고 여기에 두어야 한다고 생각합니다. 외에 싱글톤 객체가 정말로 필요한지, 또는 작업을 수행하는 작고 짧은 객체가 인스턴스화되도록 싱글톤 클래스를 다시 작성할 수도 있는지 다시 생각해 보십시오.

싱글톤을 적극 추천합니다.콘텍스트가 필요한 싱글톤이 있는 경우는, 다음과 같이 해 주세요.

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

어플리케이션보다 싱글톤을 선호합니다.이는 어플리케이션을 보다 체계적이고 모듈러형으로 유지하는 데 도움이 되기 때문입니다.앱 전체의 글로벌한 상태를 모두 유지할 필요가 있는 장소가 아니라 각각의 개별적인 요소가 알아서 처리됩니다.또한 싱글톤이 Application.onCreate()에서 모든 초기화를 사전에 실행하는 경로를 안내하는 것이 아니라 (요구에 따라) 느긋하게 초기화하는 것도 좋습니다.

싱글톤을 사용해도 본질적으로 문제될 것은 없습니다.말이 될 때 제대로 사용하세요.Android 프레임워크는 실제로 로드된 리소스 및 기타 리소스의 프로세스별 캐시를 유지하기 위해 많은 수의 캐시를 가지고 있습니다.

또한 단순한 애플리케이션의 경우 멀티스레딩은 싱글톤에서는 문제가 되지 않습니다.왜냐하면 설계상 어플리케이션에 대한 모든 표준 콜백은 프로세스의 메인 스레드에 디스패치되기 때문에 스레드를 통해 명시적으로 도입하거나 콘텐츠 프로바이더 또는 서비스 IBinder를 퍼블리시함으로써 멀티스레딩이 발생하지 않기 때문입니다.기타 프로세스

그저 네가 하고 있는 일에 대해 곰곰이 생각해 봐.:)

출처: 개발자 > 레퍼런스 - 응용 프로그램

통상, 애플리케이션을 서브 클래스 할 필요는 없습니다.대부분의 경우 스태틱싱글톤은 같은 기능을 모듈러 방식으로 제공할 수 있습니다.싱글톤에 글로벌콘텍스트가 필요한 경우(예를 들어 브로드캐스트리시버를 등록하기 위해), 이 콘텍스트를 취득하는 함수에 Context.getApplicationContext()를 사용하여 싱글톤을 최초로 구축할 수 있습니다.

어플리케이션은 싱글톤과 다릅니다.이유는 다음과 같습니다.

  1. 응용 프로그램의 메서드(onCreate 등)가 UI 스레드에서 호출됩니다.
  2. 싱글톤의 메서드는 임의의 스레드로 호출할 수 있다.
  3. 어플리케이션의 "onCreate" 메서드에서는 핸들러를 인스턴스화할 수 있습니다.
  4. 싱글톤이 none-ui 스레드에서 실행되는 경우 핸들러를 인스턴스화할 수 없습니다.
  5. 응용 프로그램에는 응용 프로그램에서 작업의 수명 주기를 관리하는 기능이 있습니다.registerActivityLifecycleCallbacks 메서드가 있습니다.하지만 싱글톤들은 능력이 없다.

저도 같은 문제가 있었습니다.싱글톤 또는 서브클래스의 Android.os를 만듭니다.응용 프로그램?

처음에 싱글톤으로 시도했는데 어느 순간 내 앱이 브라우저로 전화를 걸어온다.

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

문제는 핸드셋의 메모리가 부족하면 대부분의 클래스(싱글톤도)가 메모리를 얻기 위해 클리닝되기 때문에 브라우저에서 내 앱으로 돌아올 때 매번 크래쉬가 발생한다는 것입니다.

해결 방법: 필요한 데이터를 애플리케이션 클래스의 하위 클래스에 넣습니다.

양쪽을 동시에 고려합니다.

  • 클래스 내에 정적 인스턴스로서 싱글톤 오브젝트가 있습니다.
  • 어플리케이션 내의 모든 singelton 객체의 싱글톤인스턴스를 반환하는 공통 클래스(Context)가 있습니다.이를 통해 컨텍스트 내의 메서드명은 User.getInstance()가 아닌 context.getLoggedinUser()와 같이 의미가 있다는 장점이 있습니다.

또한 콘텍스트를 확장하여 싱글톤 객체에 대한 액세스뿐만 아니라 context.logOffUser(), context.readSavedData() 등 글로벌하게 액세스해야 하는 일부 기능을 포함할 것을 권장합니다.콘텍스트의 이름을 「파사드」로 변경하는 것은, 이치에 맞을지도 모릅니다.

사실 똑같아요.내가 볼 수 있는 한 가지 차이점이 있다.Application 클래스를 사용하면 Application.onCreate()에서 변수를 초기화하고 Application.onTerminate()에서 변수를 파기할 수 있습니다.싱글톤에서는 VM의 초기화 및 스태틱스 파괴에 의존해야 합니다.

속담에 의하면...

앱을 개발할 때 데이터, 컨텍스트 또는 서비스를 앱 전체에서 글로벌하게 공유할 필요가 있을 수 있습니다.예를 들어 현재 로그인한 사용자와 같은 세션 데이터가 앱에 있는 경우 이 정보를 노출할 수 있습니다.Android에서 이 문제를 해결하기 위한 패턴은 Android.app을 사용하는 것입니다.응용 프로그램인스턴스는 모든 글로벌데이터를 소유하여 응용 프로그램인스턴스를 다양한 데이터와 서비스에 대한 스태틱액세서를 가진 싱글톤으로 취급합니다.

Android 앱을 작성할 때 Android.app의 인스턴스는 1개뿐임을 보증합니다.애플리케이션 클래스이므로 싱글톤으로 취급하는 것이 안전합니다(Google Android 팀에서는 권장).즉, 애플리케이션 구현에 static getInstance() 메서드를 안전하게 추가할 수 있습니다.다음과 같은 경우:

public class AndroidApplication extends Application {

    private static AndroidApplication sInstance;

    public static AndroidApplication getInstance(){
        return sInstance;
    }

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

My 2 cents:

I did notice that some singleton / static fields were reseted when my activity was destroyed. I noticed this on some low end 2.3 devices.

My case was very simple : I just have a private filed "init_done" and a static method "init" that I called from activity.onCreate(). I notice that the method init was re-executing itself on some re-creation of the activity.

While I cannot prove my affirmation, It may be related to WHEN the singleton/class was created/used first. When the activity get destroyed/recycled, it seem that all class that only this activity refer are recycled too.

I moved my instance of singleton to a sub class of Application. I acces them from the application instance. and, since then, did not notice the problem again.

I hope this can help someone.

My activity calls finish() (which doesn't make it finish immediately, but will do eventually) and calls Google Street Viewer. When I debug it on Eclipse, my connection to the app breaks when Street Viewer is called, which I understand as the (whole) application being closed, supposedly to free up memory (as a single activity being finished shouldn't cause this behavior). Nevertheless, I'm able to save state in a Bundle via onSaveInstanceState() and restore it in the onCreate() method of the next activity in the stack. Either by using a static singleton or subclassing Application I face the application closing and losing state (unless I save it in a Bundle). So from my experience they are the same with regards to state preservation. I noticed that the connection is lost in Android 4.1.2 and 4.2.2 but not on 4.0.7 or 3.2.4, which in my understanding suggests that the memory recovery mechanism has changed at some point.

ReferenceURL : https://stackoverflow.com/questions/3826905/singletons-vs-application-context-in-android

반응형