Android 애플리케이션 클래스를 확장해야하는 이유


168

확장 Application클래스는 전역 변수를 선언 할 수 있습니다. 다른 이유가 있습니까?


이것은 내 머리 꼭대기에있는 아이디어 일뿐이지만 onAct를 재정의하고 MainActivity 대신 한 번의 시작 화면, 즉 사용자가 앱을 처음 열 때 소개 화면을 표시 할 수 있어야합니다.
btse

답변:


29

나는 응용 프로그램 확장이 다른 접근 방식보다 선호되거나 무언가를 달성하는 데 필요한 실제 시나리오를 생각할 수 없습니다. 값 비싸고 자주 사용되는 객체가있는 경우 객체가 현재 존재하지 않음을 감지하면 IntentService에서 객체를 초기화 할 수 있습니다. 응용 프로그램 자체는 UI 스레드에서 실행되는 반면 IntentService는 자체 스레드에서 실행됩니다.

명시 적 인 텐트를 사용하여 Activity에서 Activity로 데이터를 전달하거나 SharedPreferences를 사용하는 것을 선호합니다. 인터페이스를 사용하여 Fragment에서 상위 활동으로 데이터를 전달하는 방법도 있습니다.


39
응용 프로그램 클래스를 확장하는 데는 여러 가지 용도가 있습니다. 매우 유용한 방법 중 하나는 응용 프로그램에서 포착되지 않은 모든 예외를 포착하는 것입니다. 그래서 이것은 매우 편리합니다
png

3
어떻게합니까?
serj

8
일에 대한 "prefer to pass data from Activity to Activity with explicit Intents, or use SharedPreferences". 우리는 항상 가능한 한 많은 글로벌 상태를 제거하고 정적
var

9
왜? 어떤 시점에서 안드로이드를 다른 프로세스 또는 다른 응용 프로그램에서 재사용 할 수있는 모든 구성 요소에서 실행할 수 있도록 준비하는 것이 의도적으로 제한적입니까? 데이터 객체를 직렬화하는 대신 전달하면 CPU와 메모리가 절약됩니다. 동일 장치 내부 프로세스 핸드 오버를위한 소포 작업은 이상적이지 않습니다. 나는 실제로 intentservice가 그런 식으로 사용되는 것을 보지 못합니다 (다른 스레드를 new로 수행하십시오). 실제로 코더를 혼란스럽게 만드는 많은 것들이 구글이 추가 한 "헬퍼"가 마치 별도의 컴퓨터에서 활동을하는 것처럼 만들어 졌다는 점에서 비롯됩니다.
Lassi Kinnunen

127

소개:

여기에 이미지 설명을 입력하십시오

  1. apk모바일에서 파일을 고려하면 파일은 Activitys, Services 및 기타와 같은 여러 유용한 블록으로 구성 됩니다.
  2. 이러한 구성 요소는 서로 정기적으로 통신하지 않으며 자체 수명주기가 있다는 것을 잊지 않습니다. 한 번에 활성화되고 다른 순간에는 비활성화 될 수 있음을 나타냅니다.

요구 사항 :

  1. 때로는 사용자가 사용 Application하는 Activity것과 상관없이 변수와 그 상태에 액세스해야하는 시나리오가 필요할 수 있습니다.
  2. 예를 들어, 사용자는을 통해 액세스해야하는 직원 정보 (예 : 이름)를 보유한 변수에 액세스해야 할 수 있습니다 Application.
  3. 우리는 SQLite를 사용할 수 있지만 a를 만들고 Cursor다시 닫는 것은 성능에 좋지 않습니다.
  4. Intents를 사용 하여 데이터를 전달할 수는 있지만 메모리 사용 가능 여부에 따라 특정 시나리오에서 서투른 활동 자체가 존재하지 않을 수 있습니다.

응용 프로그램 클래스 사용 :

  1. 전역 변수에 접근 Application,
  2. 당신이 사용할 수있는 Application응용 프로그램 클래스가 먼저 시작되기 때문에 등을 분석 같은 특정 일을 시작하는 Activitys 또는 ServicesS가 실행되고있다,
  3. 애플리케이션 구성이 변경 될 때 (수평에서 수직으로 또는 그 반대로) 트리거되는 onConfigurationChanged ()라는 재정의 된 메소드가 있습니다.
  4. Android 기기의 메모리가 부족할 때 트리거되는 onLowMemory () 이벤트도 있습니다.

요구 사항 부분에서 SharedPreferences를 사용하지 않는 이유는 무엇입니까?

개인 정보 저장과 같은 첫 번째 예에서는 SharedPreferences를 사용할 수 있습니다. 그러나 마지막 부분에서 제시 한 예는 내 의심을 없 ed습니다. 감사!
Saurabh Singh

63

응용 프로그램 클래스는 응용 프로그램의 전체 수명주기가있는 개체입니다. 응용 프로그램으로 가장 높은 계층입니다. 가능한 사용법 예 :

  • Application 클래스에서 onCreate를 재정 의하여 응용 프로그램을 시작할 때 필요한 것을 추가 할 수 있습니다.

  • 활동에서 활동으로 이동하는 전역 변수를 저장하십시오. 비동기 작업처럼.

    기타


4
응용 프로그램을 전역 변수에 대한 덤프 장으로 사용하는 것은 큰 코드 냄새입니다. 이 작업을 수행하려면 고유 한 사용자 지정의 더 구체적인 클래스를 싱글 톤 또는 정적 변수와 함께 사용해야합니다.
Austin

5
@Austin 왜 냄새가 나는가?
Relm

1
그래, 왜 냄새? 앞서 언급했듯이 응용 프로그램 클래스는 계층 구조의 최상위에 있으며 사용자 지정 싱글 톤 클래스가 그 아래에 있다는 점심 돈을 걸 수 있습니다. 따라서 푸시가 발생하고 휴대 전화의 메모리가 부족하면 사용자 정의 싱글 톤이 Application 클래스 (기본적으로 전체 앱)가 아닌 가장 먼저 죽임을 당할 것이라고 말하고 싶습니다.
스타 웨이브

31

때로는 여러 활동에서 액세스 해야하는 전역 변수와 같이 데이터를 저장하려고 할 때가 있습니다. 이 경우 Application 개체가 도움이됩니다.

예를 들어, 각 http 요청에 대한 기본 인증 데이터를 얻으려면 응용 프로그램 객체에서 인증 데이터에 대한 메소드를 구현할 수 있습니다.

그 후에는 다음과 같은 활동에서 사용자 이름과 비밀번호를 얻을 수 있습니다.

MyApplication mApplication = (MyApplication)getApplicationContext();
String username = mApplication.getUsername();
String password = mApplication.getPassword();

마지막으로 Application 객체를 싱글 톤 객체로 사용해야합니다.

 public class MyApplication extends Application {
    private static MyApplication singleton;

    public MyApplication getInstance(){
        return singleton;
    }
    @Override
    public void onCreate() {
        super.onCreate();
        singleton = this;
    }
}

자세한 내용은 응용 프로그램 클래스 를 클릭하십시오


2
친절하게 이것을 설명하십시오. 왜냐하면 Application 클래스의 싱글 톤 객체를 그 자체가 싱글 톤이라는 것을 아는 한 명시 적으로 만들어야합니다. 가능한 경우 여러 개의 응용 프로그램 객체를 만들 수 있다면 어떻게해야합니까? 그리고 그 결과는 무엇입니까? 친절하게 설명하십시오.
Syed Raza Mehdi

아니요, 아마도 하나의 응용 프로그램 클래스 일 것입니다. developer.android.com/guide/topics/manifest/…
IntelliJ Amiya

그렇다면 왜 단일 객체를 명시 적으로 유지해야합니까? OS가 우리를 위해 그것을 유지하고 있지 않습니까? 실제로 활동 클래스에 응용 프로그램 객체가 있고 매니페스트에 언급되지 않은 코드가 발생했습니다. 나는 이것이 잘못되었다고 생각하고 왜 정적 싱글 톤 객체를 만들고 있는지 궁금합니다. 당신이 생각하는 것이 최선의 방법입니다. 답장을 보내 주셔서 감사합니다.
Syed Raza Mehdi

1
덕분에 나는이 링크를 여기에 내 대답을 발견 developer.android.com/reference/android/app/Application.html
에드 라자 메디

* singleton * 객체는 어디에 있습니까
Dr. aNdRO

8

Application 클래스는 모든 활동 또는 Context 객체가있는 다른 곳에서 액세스 할 수있는 싱글 톤입니다.

또한 약간의 수명주기가 있습니다.

Application의 onCreate 메소드를 사용하여 분석 도우미와 같이 비싸지 만 자주 사용되는 객체를 인스턴스화 할 수 있습니다. 그런 다음 어디서나 해당 객체에 액세스하여 사용할 수 있습니다.


6
"또한 약간의 수명주기가 있습니다." 당신은 그것을 다시 말하고 싶을 수도 있습니다.
wtsang02

2
나는 당신이 약간의 수명주기 전화를 받았지만 활동이나 단편만큼 많지는 않다는 것을 의미합니다. 예를 들어, Application 클래스에는 onDestroy ()가 없습니다.
Jon F Hancock

이 클래스는 자동으로 생성됩니까?
Konstantin Konopko

예. AndroidManifest.xml에서 올바르게 지정하기 만하면됩니다.
Jon F Hancock

아니요, 자동으로 생성되지 않습니다. 파일을 생성 한 다음 매니페스트 파일에서 선언해야합니다.
Ojonugwa Jude Ochalifu

7

응용 프로그램 클래스를 가장 잘 사용합니다. 예 : 부팅이 완료되면 알람 관리자를 다시 시작해야한다고 가정합니다.

public class BaseJuiceApplication extends Application implements BootListener {

    public static BaseJuiceApplication instance = null;

    public static Context getInstance() {
        if (null == instance) {
            instance = new BaseJuiceApplication();
        }
        return instance;
    }

    @Override
    public void onCreate() {
        super.onCreate();


    }

    @Override
    public void onBootCompleted(Context context, Intent intent) {
        new PushService().scheduleService(getInstance());
        //startToNotify(context);
    }

getApplication ()을 사용하여 응용 프로그램 객체에 대한 정적 참조를 작성 해야하는 이유가 궁금합니다. 내가이 개념을 이해하는 한 응용 프로그램 클래스는 OS 자체에 의해 만들어지며 OS에 의해 유지 관리되는 인스턴스는 하나만 있어야합니다. 친절하게 설명, 감사합니다.
Syed Raza Mehdi

당신은 맞습니다. 앱의 애플리케이션 구성 요소에서 getApplication을 호출하면 앱인 단일 Application 파생 인스턴스가 반환됩니다. 이것은 Android 프레임 워크에서 내부적으로 처리됩니다. 리턴 된 인스턴스를 Application을 확장하는 사용자 정의 클래스로 캐스트하면됩니다. 또한 인스턴스를 인스턴스화하기 위해 Android 프레임 워크에서 적절한 클래스를 사용하도록 적절하게 매니페스트를 설정해야합니다.
매트 웰케

5

답이 아니라 관찰 : 확장 응용 프로그램 객체의 데이터 는 동일한 활동의 ​​두 인스턴스가 동시에 실행될 수 있기 때문에 활동의 인스턴스와 연결되어서는 안됩니다 . 전경과 보이지 않는 것) .

예를 들어 실행기를 통해 정상적으로 활동을 시작한 다음 "최소화"합니다. 그런 다음 앱이 android.intent.action.CREATE_SHORTCUT을 지원하기 때문에 바로 가기를 생성하기 위해 다른 앱 (예 : Tasker)을 시작하여 다른 액티비티 인스턴스를 시작합니다. 그런 다음 바로 가기가 작성되고 활동의이 바로 가기 작성 호출이 데이터를 애플리케이션 오브젝트로 수정 한 경우, 백그라운드에서 실행중인 활동이이 수정 된 애플리케이션 오브젝트가 포 그라운드로 다시 돌아 오면 사용을 시작합니다.


4

이 질문에 답이 없습니다. ApplicationBill Pugh Singleton 구현 ( reference 참조 )을 사용하고 일부 싱글 톤에는 컨텍스트가 필요 하기 때문에 확장 합니다. Application이 같은 클래스 외모 :

public class MyApplication extends Application {

    private static final String TAG = MyApplication.class.getSimpleName();

    private static MyApplication sInstance;

    @Contract(pure = true)
    @Nullable
    public static Context getAppContext() {
        return sInstance;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate() called");
        sInstance = this;
    }
}

그리고 싱글 톤은 다음과 같습니다 :

public class DataManager {

    private static final String TAG = DataManager.class.getSimpleName();

    @Contract(pure = true)
    public static DataManager getInstance() {
        return InstanceHolder.INSTANCE;
    }

    private DataManager() {
        doStuffRequiringContext(MyApplication.getAppContext());
    }

    private static final class InstanceHolder {
        @SuppressLint("StaticFieldLeak")
        private static final DataManager INSTANCE = new DataManager();
    }
}

이 방법으로 싱글 톤을 사용할 때마다 컨텍스트를 가질 필요가 없으며 최소한의 코드로 동기화 된 초기화를 얻습니다.

팁 : Android Studio 싱글 톤 템플릿을 업데이트하면 많은 시간이 절약됩니다.


3

나는 당신이 많은 것들을 위해 Application 클래스를 사용할 수 있다고 생각하지만, 활동이나 서비스가 시작되기 전에 어떤 것들을해야 할 필요성에 묶여 있습니다. 예를 들어, 내 응용 프로그램에서 사용자 정의 글꼴을 사용합니다. 전화하는 대신

Typeface.createFromAsset()

자산 폴더에서 내 글꼴에 대한 참조를 (당신이 자산에 대한 참조 해당 메서드를 호출 할 때마다 유지되는대로 메모리 누수가 발생합니다 때문에 나쁜) 얻을 수있는 모든 활동에서, 난에서 이렇게 onCreate()내 응용 프로그램의 메소드 :

private App appInstance;
Typeface quickSandRegular;
...
public void onCreate() {
    super.onCreate();

    appInstance = this;
    quicksandRegular = Typeface.createFromAsset(getApplicationContext().getAssets(),
                       "fonts/Quicksand-Regular.otf");
   ...
   }

이제 다음과 같이 정의 된 메소드가 있습니다.

public static App getAppInstance() {
    return appInstance;
}

이:

public Typeface getQuickSandRegular() {
    return quicksandRegular;
}

따라서 응용 프로그램의 어느 곳에서나해야 할 일은 다음과 같습니다.

App.getAppInstance().getQuickSandRegular()

나를 위해 Application 클래스를 사용하는 또 다른 용도는 연결이 필요한 활동 및 서비스가 실제로 시작되고 필요한 조치를 취하기 전에 장치가 인터넷에 연결되어 있는지 확인하는 것입니다.


1
잘했다. 아주 좋은 고장.
Oluwatobi Adenekan

3

출처 : https://github.com/codepath/android_guides/wiki/Understanding-the-Android-Application-Class

많은 앱에서 애플리케이션 클래스로 직접 작업 할 필요가 없습니다. 그러나 사용자 정의 응용 프로그램 클래스는 몇 가지 허용되는 용도로 사용됩니다.

  • 첫 번째 활동을 만들기 전에 실행해야하는 전문화 된 작업
  • 모든 구성 요소에서 공유해야하는 전역 초기화 (충돌보고, 지속성)
  • 공유 네트워크 클라이언트 객체와 같은 정적 불변 데이터에 쉽게 액세스 할 수있는 정적 메소드

변경 가능한 인스턴스 데이터를 Application 객체 내에 저장해서는 안됩니다. 데이터가 그대로 있다고 가정하면 NullPointerException이 발생하는 시점에서 애플리케이션이 필연적으로 충돌하기 때문입니다. 응용 프로그램 객체가 메모리에 영원히 남아 있다고 보장되지는 않으며 죽습니다. 일반적인 믿음과는 달리 앱은 처음부터 다시 시작되지 않습니다. Android는 새로운 Application 객체를 생성하고 사용자가 이전에 애플리케이션을 종료 한 적이 없다는 착각을주기 위해 사용자가 활동했던 활동을 시작합니다.


1

Application에서 확장 한 개체를 만들지 않고도 모든 클래스에 변수에 액세스 할 수 있습니다. 전역 적으로 호출 할 수 있으며 응용 프로그램이 종료되지 않을 때까지 상태가 유지됩니다.


1

응용 프로그램 확장을 사용하면 응용 프로그램 실행 기간 동안 원하는 모든 종류의 작업을 수행 할 수 있습니다. 이제는 모든 종류의 변수가 될 수 있으며 서버에서 일부 데이터를 가져 오려는 경우 asynctask를 응용 프로그램에 배치하여 매번 지속적으로 가져 오므로 업데이트 된 데이터를 자동으로 가져올 수 있습니다 ..이 링크를 사용하십시오. 더 많은 지식을 얻으려면 ....

http://www.intridea.com/blog/2011/5/24/how-to-use-application-object-of-android


스레드가 아니므로 "응용 프로그램 실행 기간 동안 원하는 모든 종류의 작업"에 적합합니다. 사실이 아닙니다.
Lassi Kinnunen

1

활동을 사용하지 않는 응용 프로그램에 바인딩 해야하는 장기 실행 스레드 또는 기타 객체 (응용 프로그램은 활동이 아님)에 대해 응용 프로그램 범위에서 저장 변수를 원할 수 있다는 다른 대답을 추가합니다. 바인드 된 서비스를 요청할 수없는 것과 같이. 애플리케이션 인스턴스에 바인딩하는 것이 바람직합니다. 이 접근 방식의 유일한 확실한 경고는 응용 프로그램이 존재하는 한 객체가 존재한다는 것이므로 메모리에 대한 암시 적 제어가 필요합니다. 그렇지 않으면 누출과 같은 메모리 관련 문제가 발생합니다.

유용한 다른 작업은 작업 순서에서 응용 프로그램이 활동보다 먼저 시작된다는 것입니다. 이 기간 동안 원하는 경우 첫 번째 활동 전에 발생할 수있는 하우스 키핑을 준비 할 수 있습니다.

2018-10-19 11:31:55.246 8643-8643/: application created
2018-10-19 11:31:55.630 8643-8643/: activity created
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.