Por que estender a classe Aplicativo Android?

168

Uma Applicationclasse estendida pode declarar variáveis ​​globais. Existem outras razões?

TN888
fonte
Isso é apenas uma ideia, mas você deve substituir o onCreate e exibir uma tela de inicialização única em vez da MainActivity, ou seja, uma tela de introdução na primeira vez em que o usuário abre o aplicativo.
BTSE

Respostas:

29

Imediatamente, não consigo pensar em um cenário real no qual estender o Aplicativo seja preferível a outra abordagem ou necessário para realizar alguma coisa. Se você tiver um objeto caro e usado com frequência, poderá inicializá-lo em um IntentService quando detectar que o objeto não está presente no momento. O próprio aplicativo é executado no thread da interface do usuário, enquanto o IntentService é executado no seu próprio thread.

Prefiro passar dados de Activity para Activity com Intents explícitos ou usar SharedPreferences. Também existem maneiras de passar dados de um Fragmento para sua Atividade pai usando interfaces.

Joe Malin
fonte
39
Há muitos usos da extensão da classe de aplicativo. Um muito útil é capturar todas as exceções não capturadas em seu aplicativo. Então isso é algo que pode ser muito útil
png
3
Como você faz isso ?
22315 serj
8
+1 para "prefer to pass data from Activity to Activity with explicit Intents, or use SharedPreferences". Devemos sempre eliminar estado global tanto quanto podemos e usar ferramentas padrão do Android para o gerenciamento global do estado em vez de estática vars / singletons e etc.
Oleksandr Karaberov
9
porque? se preparar para o Android em algum momento, executando-os em diferentes processos ou qualquer outro componente reutilizável por qualquer aplicativo, enquanto isso é intencionalmente limitado? apenas passar os objetos de dados em vez de serializá-los economiza CPU e memória. empacotar material para transferências dentro do processo no mesmo dispositivo não é ideal de forma alguma. Realmente não vejo o ponto do serviço intents usado dessa maneira (basta fazer o outro thread com o novo). Na verdade, muitas das coisas que confundem os codificadores são provenientes de praticamente todos os "ajudantes" adicionados pelo Google, como se as atividades fossem executadas em computadores separados.
Lassi Kinnunen
127

Introdução:

insira a descrição da imagem aqui

  1. Se considerarmos um apkarquivo em nosso celular, ele é composto por vários blocos úteis, como Activitys,Service outros.
  2. Esses componentes não se comunicam regularmente e não esquecem que têm seu próprio ciclo de vida. o que indica que eles podem estar ativos ao mesmo tempo e inativos no outro momento.

Requisitos:

  1. Às vezes, podemos exigir um cenário em que precisamos acessar uma variável e seus estados em todo o todo, Applicationindependentemente do Activityusuário que estiver usando,
  2. Um exemplo é que um usuário pode precisar acessar uma variável que contém suas informações pessoais (por exemplo, nome) que precisam ser acessadas através de Application,
  3. Podemos usar o SQLite, mas criar Cursore fechá-lo repetidamente não é bom em desempenho,
  4. Poderíamos usar Intents para passar os dados, mas é desajeitado e a própria atividade pode não existir em um determinado cenário, dependendo da disponibilidade de memória.

Usos da Classe de Aplicação:

  1. Acesso a variáveis ​​entre Application,
  2. Você pode usar o Applicationpara iniciar certas coisas, como análises, etc., pois a classe do aplicativo é iniciada antes da execução de Activitys ou Servicess,
  3. Existe um método substituído chamado onConfigurationChanged () que é acionado quando a configuração do aplicativo é alterada (horizontal para vertical e vice-versa),
  4. Há também um evento chamado onLowMemory () que é acionado quando o dispositivo Android está com pouca memória.
Devrath
fonte
Na parte de requisitos, por que não usar SharedPreferences?
No 1º exemplo, como para salvar informações pessoais, SharedPreferences pode ser usado. Mas os exemplos que você deu na última parte tiraram minhas dúvidas. Obrigado!
Saurabh Singh
63

Classe de aplicativo é o objeto que possui o ciclo de vida completo do seu aplicativo. É a sua camada mais alta como um aplicativo. exemplo de possíveis usos:

  • Você pode adicionar o que precisa quando o aplicativo é iniciado, substituindo onCreate na classe Application.

  • armazene variáveis ​​globais que saltam de Atividade para Atividade. Como o Asynctask.

    etc

wtsang02
fonte
4
Usar o Application como um depósito de lixo para variáveis ​​globais do aplicativo é um grande cheiro de código. Você deve usar suas próprias classes personalizadas e mais específicas como singletons ou com variáveis ​​estáticas para fazer isso.
Austin
5
@ Austin, por que é um cheiro?
Relm
1
Sim, por que cheirar? Como afirmado anteriormente, a classe Application está no topo da hierarquia, e posso apostar meu dinheiro do almoço, porque uma classe singleton personalizada está abaixo dela. Portanto, se a pressão chegar, e seu telefone estiver com pouca memória, eu diria que o singleton personalizado é o primeiro a ser morto, em vez da classe Application (que é essencialmente o aplicativo inteiro).
Starwave
31

Às vezes, você deseja armazenar dados, como variáveis ​​globais que precisam ser acessadas de várias atividades - às vezes em qualquer lugar do aplicativo. Nesse caso, o objeto Aplicativo o ajudará.

Por exemplo, se você deseja obter os dados básicos de autenticação para cada solicitação http , pode implementar os métodos para dados de autenticação no objeto de aplicativo.

Depois disso, você pode obter o nome de usuário e a senha em qualquer uma das atividades como esta:

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

E, finalmente, lembre-se de usar o objeto Aplicativo como um objeto singleton:

 public class MyApplication extends Application {
    private static MyApplication singleton;

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

Para mais informações, clique em Classe de Aplicação

IntelliJ Amiya
fonte
2
por favor, explique-me isso, por que precisamos fazer explicitamente o objeto singleton de uma classe Application, tanto quanto eu sei que ele próprio é um singleton. Podemos criar vários objetos de aplicação, se pudermos, então como? e quais são as consequências? Por favor, explique.
Syed Raza Mehdi
Não, provavelmente apenas uma classe de aplicativo. developer.android.com/guide/topics/manifest/…
IntelliJ Amiya
então por que precisamos manter explicitamente o objeto singleton dele? O SO não está mantendo isso para nós? Na verdade, encontrei um código no qual existe um objeto de aplicativo criado na classe de atividade e ele não está sendo mencionado no manifesto. Eu acho que isso está errado, também estou curioso por que estamos criando objetos singleton estáticos. O que você acha que é a melhor abordagem. Obrigado por responder.
Syed Raza Mehdi
1
obrigado Encontrei a minha resposta aqui neste link developer.android.com/reference/android/app/Application.html
Syed Raza Mehdi
Onde está o objeto * singleton * nisso
Dr. aNdRO 13/09/17
8

A classe Application é um singleton que você pode acessar de qualquer atividade ou de qualquer outro lugar que possua um objeto Context.

Você também recebe um pouco do ciclo de vida.

Você pode usar o método onCreate do aplicativo para instanciar objetos caros, mas frequentemente usados, como um auxiliar de análise. Então você pode acessar e usar esses objetos em qualquer lugar.

Jon F Hancock
fonte
6
"Você também recebe um pouco do ciclo de vida." você pode reformular isso.
Wtsang02
2
Quero dizer, você recebe algumas chamadas do ciclo de vida, mas não tantas quanto uma atividade ou fragmento. Por exemplo, não há onDestroy () para a classe Application.
Jon F Hancock
Essa classe é criada automaticamente?
Konstantin Konopko 19/03/2015
Sim. Contanto que você o especifique corretamente no AndroidManifest.xml.
Jon F Hancock
Não, ele não é criado automaticamente. Você precisa criá-lo e depois declará-lo no arquivo de manifesto.
Ojonugwa Jude Ochalifu
7

Melhor uso da classe de aplicativo. Exemplo: suponha que você precise reiniciar o gerenciador de alarmes na inicialização concluída.

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);
    }
Srishti Roy
fonte
Eu estou querendo saber por que precisamos fazer uma referência estática do objeto de aplicativo, onde podemos obtê-lo usando getApplication () e convertê-lo na classe de aplicativo. Até onde eu entendi esse conceito, a classe de aplicativo é feita pelo próprio sistema operacional e deve ter apenas uma instância que é mantida pelo sistema operacional. Por favor, explique, obrigado.
Syed Raza Mehdi
Você está certo. Chamar getApplication a partir de qualquer componente do aplicativo em seu aplicativo retorna a única instância derivada do aplicativo que é seu aplicativo. Isso é tratado internamente pela estrutura do Android. Tudo o que você precisa fazer é converter a instância retornada para sua classe personalizada que estende o Application. Você também precisa definir seu manifesto adequadamente para que a classe apropriada seja usada pela estrutura do Android para instanciar a instância.
Matt Welke
5

Não é uma resposta, mas uma observação : lembre-se de que os dados no objeto de aplicativo estendido não devem estar vinculados a uma instância de uma atividade, pois é possível que você tenha duas instâncias da mesma atividade em execução ao mesmo tempo (uma em primeiro plano e um não sendo visível) .

Por exemplo, você inicia sua atividade normalmente através do iniciador e, em seguida, "minimiza". Em seguida, você inicia outro aplicativo (ou seja, Tasker), que inicia outra instância de sua atividade, por exemplo, para criar um atalho, porque seu aplicativo suporta android.intent.action.CREATE_SHORTCUT. Se o atalho for criado e essa invocação da atividade de criação de atalhos modificou os dados do objeto de aplicativo, a atividade em execução em segundo plano começará a usar esse objeto de aplicativo modificado depois que ele for trazido de volta ao primeiro plano.

Daniel F
fonte
4

Vejo que esta pergunta está faltando uma resposta. Estendo Applicationporque uso a implementação de Bill Pugh Singleton ( consulte a referência ) e alguns de meus singletons precisam de contexto. A Applicationclasse fica assim:

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;
    }
}

E os singletons ficam assim:

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();
    }
}

Dessa forma, não preciso ter um contexto toda vez que estiver usando um singleton e obter uma inicialização sincronizada lenta com uma quantidade mínima de código.

Dica: a atualização do modelo singleton do Android Studio economiza muito tempo.

Sir Codesalot
fonte
3

Acho que você pode usar a classe Application para muitas coisas, mas todas elas estão ligadas à sua necessidade de fazer algumas coisas ANTES de qualquer uma das suas Atividades ou Serviços ser iniciada. Por exemplo, no meu aplicativo eu uso fontes personalizadas. Em vez de ligar

Typeface.createFromAsset()

de cada Activity para obter referências para minhas fontes na pasta Assets (isso é ruim porque resultará em vazamento de memória, pois você mantém uma referência a ativos toda vez que chama esse método), faço isso no onCreate()método da minha classe Application :

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

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

Agora, eu também tenho um método definido assim:

public static App getAppInstance() {
    return appInstance;
}

e isto:

public Typeface getQuickSandRegular() {
    return quicksandRegular;
}

Portanto, de qualquer lugar do meu aplicativo, tudo o que preciso fazer é:

App.getAppInstance().getQuickSandRegular()

Outro uso para a classe Application para mim é verificar se o dispositivo está conectado à Internet ANTES de atividades e serviços que requerem conexão realmente iniciarem e tomarem as medidas necessárias.

Ojonugwa Jude Ochalifu
fonte
1
Bem dito. Very Nice quebrar.
Oluwatobi Adenekan
3

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

Em muitos aplicativos, não há necessidade de trabalhar diretamente com uma classe de aplicativo. No entanto, existem alguns usos aceitáveis ​​de uma classe de aplicativo personalizada:

  • Tarefas especializadas que precisam ser executadas antes da criação de sua primeira atividade
  • Inicialização global que precisa ser compartilhada entre todos os componentes (relatório de falha, persistência)
  • Métodos estáticos para facilitar o acesso a dados estáticos e imutáveis, como um objeto cliente de rede compartilhado

Você nunca deve armazenar dados de instância mutáveis ​​dentro do objeto Aplicativo, porque se você presumir que seus dados permanecerão lá, seu aplicativo inevitavelmente travará em algum momento com uma NullPointerException. Não é garantido que o objeto do aplicativo fique na memória para sempre; ele será morto. Ao contrário da crença popular, o aplicativo não será reiniciado do zero. O Android criará um novo objeto Aplicativo e iniciará a atividade em que o usuário estava antes para dar a ilusão de que o aplicativo nunca foi morto.

Periworks
fonte
1

Você pode acessar variáveis ​​para qualquer classe sem criar objetos, se este for estendido pelo Aplicativo. Eles podem ser chamados globalmente e seu estado é mantido até que o aplicativo não seja interrompido.

Taran Mahal
fonte
1

O uso do aplicativo de extensão apenas garante seu aplicativo para qualquer tipo de operação que você deseja durante o período de execução do aplicativo. Agora, pode haver qualquer tipo de variável e, suponha que, se você deseja buscar alguns dados do servidor, pode colocar o seu assíncrono no aplicativo para que ele seja buscado sempre e continuamente, para que você obtenha dados atualizados automaticamente. Use este link para mais conhecimento ....

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

Vishal Jain
fonte
não é um encadeamento, portanto "para qualquer tipo de operação que você deseja durante o período de execução do aplicativo". não é verdade.
Lassi Kinnunen
1

Para adicionar às outras respostas que afirmam que você pode desejar armazenar variáveis ​​no escopo do aplicativo, para quaisquer threads de execução longa ou outros objetos que precisem ser vinculados ao seu aplicativo em que você NÃO esteja usando uma atividade (o aplicativo não é uma atividade) .. como não poder solicitar um serviço vinculado. a ligação à instância do aplicativo é preferida. O único aviso óbvio com essa abordagem é que os objetos permanecem ativos enquanto o aplicativo estiver ativo, portanto, é necessário um controle implícito sobre a memória, caso contrário, você encontrará problemas relacionados à memória, como vazamentos.

Outra coisa que você pode achar útil é que, na ordem das operações, o aplicativo inicia primeiro antes de qualquer atividade. Nesse período, você pode preparar qualquer serviço de limpeza necessário que ocorra antes da sua primeira atividade, se assim o desejar.

2018-10-19 11:31:55.246 8643-8643/: application created
2018-10-19 11:31:55.630 8643-8643/: activity created
David Maki
fonte