¿Por qué extender la clase de aplicación de Android?

168

Una Applicationclase extendida puede declarar variables globales. ¿Hay otras razones?

TN888
fuente
Esta es solo una idea fuera de mi cabeza, pero debería ser capaz de anular onCreate y mostrar una pantalla de inicio única en lugar de MainActivity, es decir, una pantalla de introducción la primera vez que el usuario abre la aplicación.
btse

Respuestas:

29

Por otro lado, no puedo pensar en un escenario real en el que extender la aplicación sea preferible a otro enfoque o sea necesario para lograr algo. Si tiene un objeto costoso y de uso frecuente, puede inicializarlo en un IntentService cuando detecte que el objeto no está presente actualmente. La aplicación en sí se ejecuta en el subproceso de la interfaz de usuario, mientras que IntentService se ejecuta en su propio subproceso.

Prefiero pasar datos de Actividad a Actividad con intenciones explícitas, o usar SharedPreferences. También hay formas de pasar datos de un Fragmento a su Actividad principal utilizando interfaces.

Joe Malin
fuente
39
Hay muchos usos de extender la clase de aplicación. Una muy útil es detectar todas las excepciones no detectadas en su aplicación. Así que esto es algo que puede ser muy útil
png
3
Cómo haces eso ?
serj
8
+1 para "prefer to pass data from Activity to Activity with explicit Intents, or use SharedPreferences". Siempre debemos eliminar el estado global tanto como podamos y usar herramientas estándar de Android para la gestión global del estado en lugar de variables estáticas / singletons, etc.
Oleksandr Karaberov
9
¿por qué? para prepararse para Android en algún momento ejecutándolos en diferentes procesos o lo que sea y cada componente sea reutilizable por cualquier aplicación, mientras que eso es intencionalmente limitado? simplemente pasar los objetos de datos en lugar de serializarlos ahorra CPU y memoria. parcelar cosas para transferencias dentro del proceso en el mismo dispositivo no es ideal de ninguna manera. Realmente no veo el punto de uso de intentservice así (solo haga el otro hilo con new). En realidad, muchas de las cosas que confunden a los codificadores provienen de que casi todos los "ayudantes" agregados por Google se hacen como si las actividades se ejecutaran en computadoras separadas.
Lassi Kinnunen
127

Introducción:

ingrese la descripción de la imagen aquí

  1. Si consideramos un apkarchivo en nuestro dispositivo móvil, está compuesto por múltiples bloques útiles como, Activitys, Servicesy otros.
  2. Estos componentes no se comunican entre sí regularmente y no olviden que tienen su propio ciclo de vida. que indican que pueden estar activos en un momento e inactivos en el otro momento.

Requisitos:

  1. En ocasiones, es posible que necesitemos un escenario en el que necesitemos acceder a una variable y sus estados en todo el sistema, Applicationindependientemente del Activityusuario que esté utilizando,
  2. Un ejemplo es que un usuario puede necesitar acceder a una variable que contiene su información de personal (por ejemplo, nombre) a la que se debe acceder a través de Application,
  3. Podemos usar SQLite pero crear Cursory cerrarlo una y otra vez no es bueno para el rendimiento,
  4. Podríamos usar Intents para pasar los datos, pero es torpe y la actividad en sí misma puede no existir en un determinado escenario, dependiendo de la disponibilidad de memoria.

Usos de la clase de aplicación:

  1. Acceso a variables a través de Application,
  2. Se puede utilizar el Applicationpara iniciar ciertas cosas como la analítica etc. ya que la clase de aplicación se inicia antes de Activitys o Servicess están en ejecución,
  3. Existe un método anulado llamado onConfigurationChanged () que se activa cuando se cambia la configuración de la aplicación (horizontal a vertical y viceversa),
  4. También hay un evento llamado onLowMemory () que se activa cuando el dispositivo Android tiene poca memoria.
Devrath
fuente
En su parte de Requisitos, ¿por qué no usar SharedPreferences?
En el primer ejemplo, como para guardar información personal, se pueden usar SharedPreferences. Pero los ejemplos que diste en la última parte aclararon mis dudas. ¡Gracias!
Saurabh Singh
63

La clase de aplicación es el objeto que tiene el ciclo de vida completo de su aplicación. Es su capa más alta como aplicación. ejemplos de posibles usos:

  • Puede agregar lo que necesita cuando se inicia la aplicación anulando onCreate en la clase Aplicación.

  • almacenar variables globales que saltan de Actividad a Actividad. Como Asynctask.

    etc.

wtsang02
fuente
44
Usar la aplicación como un vertedero para las variables globales de la aplicación es un gran olor a código. Debería usar sus propias clases personalizadas y más específicas como singletons o con variables estáticas para lograr esto.
Austin
55
@Austin ¿por qué es un olor?
Relm
1
Sí, ¿por qué hueles? Como se indicó anteriormente, la clase de aplicación está en la parte superior de la jerarquía, y puedo apostar mi dinero de almuerzo, que una clase de singleton personalizada está debajo de ella. Entonces, si el empuje llega a su fin, y su teléfono tiene poca memoria, diría que el singleton personalizado es el primero en ser asesinado, en lugar de la clase de Aplicación (que esencialmente es su aplicación completa).
Starwave
31

A veces desea almacenar datos, como variables globales a las que se debe acceder desde múltiples actividades, a veces en todas partes dentro de la aplicación. En este caso, el objeto Aplicación te ayudará.

Por ejemplo, si desea obtener los datos básicos de autenticación para cada solicitud http , puede implementar los métodos para los datos de autenticación en el objeto de la aplicación.

Después de esto, puede obtener el nombre de usuario y la contraseña en cualquiera de las actividades como esta:

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

Y finalmente, recuerde usar el objeto Aplicación como un 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 obtener más información, haga clic en Clase de aplicación

IntelliJ Amiya
fuente
2
amablemente explícame esto, por qué necesitamos hacer explícitamente un objeto singleton de una clase de Aplicación, por lo que sé, es en sí mismo un singleton. ¿Podemos hacer múltiples objetos de aplicación, si podemos, entonces cómo? y cuales son las consecuencias? Por favor explique.
Syed Raza Mehdi
No, probablemente solo una clase de aplicación. developer.android.com/guide/topics/manifest/…
IntelliJ Amiya
entonces, ¿por qué necesitamos mantener explícitamente el objeto singleton de él? ¿El sistema operativo no nos lo mantiene? En realidad, encontré un código en el que hay un objeto de aplicación hecho en la clase de actividad y no se menciona en manifiesto. Creo que esto está mal, también tengo curiosidad de por qué estamos haciendo un objeto estático singleton. Lo que crees que es el mejor enfoque. Gracias por responder.
Syed Raza Mehdi
1
gracias. Encontré mi respuesta aquí en este enlace developer.android.com/reference/android/app/Application.html
Syed Raza Mehdi
¿Dónde está el objeto * singleton * en eso
Dr. aNdRO
8

La clase de aplicación es un singleton al que puede acceder desde cualquier actividad o en cualquier otro lugar donde tenga un objeto Context.

También obtienes un poco de ciclo de vida.

Puede usar el método onCreate de la aplicación para crear instancias de objetos caros, pero de uso frecuente, como un ayudante de análisis. Entonces puede acceder y usar esos objetos en todas partes.

Jon F Hancock
fuente
66
"También obtienes un poco de ciclo de vida". es posible que desee reformular eso.
wtsang02
2
Quiero decir que recibe algunas llamadas de ciclo de vida, pero no tantas como con una actividad o fragmento. Por ejemplo, no hay onDestroy () para la clase Aplicación.
Jon F Hancock
¿Esta clase se crea automáticamente?
Konstantin Konopko
Si. Siempre que lo especifique correctamente en su AndroidManifest.xml.
Jon F Hancock el
No, no se crea automáticamente. Debe crearlo y luego declararlo en su archivo de manifiesto
Ojonugwa Jude Ochalifu
7

Mejor uso de la clase de aplicación. Ejemplo: suponga que necesita reiniciar su administrador de alarmas al finalizar el arranque.

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
fuente
Me pregunto por qué necesitamos hacer una referencia estática del objeto de la aplicación, donde podemos obtenerlo usando getApplication () y escribirlo en la clase de la aplicación. Hasta donde entendí este concepto, la clase de aplicación está hecha por el sistema operativo en sí y solo debe tener una instancia que el sistema operativo mantenga. Por favor explique, gracias.
Syed Raza Mehdi
Estás en lo correcto. Llamar a getApplication desde cualquier componente de la aplicación en su aplicación devuelve la única instancia derivada de la aplicación que es su aplicación. Esto se maneja internamente por el marco de Android. Todo lo que necesita hacer es transmitir esa instancia devuelta a su clase personalizada que extiende la Aplicación. También debe configurar su manifiesto en consecuencia para que el marco de Android use la clase adecuada para crear una instancia de la instancia.
Matt Welke
5

No es una respuesta, sino una observación : tenga en cuenta que los datos en el objeto de aplicación extendida no deben estar vinculados a una instancia de una actividad, ya que es posible que tenga dos instancias de la misma actividad ejecutándose al mismo tiempo (una en el primer plano y uno no visible) .

Por ejemplo, comienza su actividad normalmente a través del iniciador y luego la "minimiza". Luego inicia otra aplicación (es decir, Tasker) que inicia otra instancia de su actividad, por ejemplo, para crear un acceso directo, porque su aplicación es compatible con android.intent.action.CREATE_SHORTCUT. Si se crea el acceso directo y esta invocación de creación de acceso directo de la actividad modificó los datos del objeto de la aplicación, entonces la actividad que se ejecuta en segundo plano comenzará a usar este objeto de aplicación modificado una vez que se vuelva a poner en primer plano.

Daniel F
fuente
4

Veo que a esta pregunta le falta una respuesta. Extiendo Applicationporque uso la implementación de Bill Pugh Singleton ( ver referencia ) y algunos de mis singletons necesitan contexto. La Applicationclase se ve así:

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

Y los singletons se ven así:

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

De esta manera, no necesito tener un contexto cada vez que estoy usando un singleton y obtener una inicialización sincronizada diferida con una cantidad mínima de código.

Consejo: la actualización de la plantilla Singleton de Android Studio ahorra mucho tiempo.

Sir Codesalot
fuente
3

Creo que puede usar la clase Aplicación para muchas cosas, pero todas están vinculadas a su necesidad de hacer algunas cosas ANTES de que se inicien sus Actividades o Servicios. Por ejemplo, en mi aplicación utilizo fuentes personalizadas. En lugar de llamar

Typeface.createFromAsset()

de cada Actividad para obtener referencias para mis fuentes de la carpeta Activos (esto es malo porque dará como resultado una pérdida de memoria ya que mantiene una referencia a los activos cada vez que llame a ese método), hago esto desde el onCreate()método en mi clase de Aplicación :

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

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

Ahora, también tengo un método definido así:

public static App getAppInstance() {
    return appInstance;
}

y esto:

public Typeface getQuickSandRegular() {
    return quicksandRegular;
}

Entonces, desde cualquier lugar de mi aplicación, todo lo que tengo que hacer es:

App.getAppInstance().getQuickSandRegular()

Otro uso para la clase de Aplicación para mí es verificar si el dispositivo está conectado a Internet ANTES de que las actividades y servicios que requieren una conexión realmente se inicien y tomen las medidas necesarias.

Ojonugwa Jude Ochalifu
fuente
1
Bien dicho. Muy bonito desglose.
Oluwatobi Adenekan
3

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

En muchas aplicaciones, no es necesario trabajar directamente con una clase de aplicación. Sin embargo, hay algunos usos aceptables de una clase de aplicación personalizada:

  • Tareas especializadas que deben ejecutarse antes de la creación de su primera actividad.
  • Inicialización global que debe compartirse entre todos los componentes (informe de fallos, persistencia)
  • Métodos estáticos para facilitar el acceso a datos inmutables estáticos, como un objeto de cliente de red compartido

Nunca debe almacenar datos de instancia mutable dentro del objeto Aplicación porque si asume que sus datos permanecerán allí, su aplicación inevitablemente se bloqueará en algún momento con una NullPointerException. No se garantiza que el objeto de la aplicación permanezca en la memoria para siempre, se eliminará. Contrariamente a la creencia popular, la aplicación no se reiniciará desde cero. Android creará un nuevo objeto Aplicación y comenzará la actividad donde el usuario estaba antes para dar la ilusión de que la aplicación nunca fue eliminada en primer lugar.

Periworks
fuente
1

Puede acceder a las variables a cualquier clase sin crear objetos, si es extendido por la aplicación. Se les puede llamar globalmente y su estado se mantiene hasta que no se elimine la aplicación.

taran mahal
fuente
1

El uso de la aplicación de extensión solo hace que su aplicación sea segura para cualquier tipo de operación que desee durante todo el período de ejecución de la aplicación. Ahora puede ser cualquier tipo de variables y supongamos que si desea obtener algunos datos del servidor, puede poner su asinctask en la aplicación para que obtenga cada vez y de forma continua, de modo que obtenga datos actualizados automáticamente. Use este enlace para más conocimiento ...

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

Vishal Jain
fuente
no es un hilo, así que "para cualquier tipo de operación que desee durante el período de ejecución de su aplicación". no es verdad.
Lassi Kinnunen
1

Para agregar a las otras respuestas que indican que es posible que desee almacenar variables en el ámbito de aplicación, para cualquier subproceso de larga ejecución u otros objetos que necesiten vincularse a su aplicación donde NO está utilizando una actividad (la aplicación no es una actividad). como no poder solicitar un servicio enlazado ... entonces se prefiere el enlace a la instancia de la aplicación. La única advertencia obvia con este enfoque es que los objetos viven mientras la aplicación esté viva, por lo que se requiere un control más implícito sobre la memoria, de lo contrario, se encontrarán problemas relacionados con la memoria, como fugas.

Otra cosa que puede resultarle útil es que, en el orden de las operaciones, la aplicación se inicia primero antes de cualquier actividad. En este período de tiempo, puede preparar cualquier limpieza necesaria que ocurriría antes de su primera actividad si así lo desea.

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