2011-07-21 13 views
10

he escrito algunas aplicaciones de Android, y siempre han declarado a partir Activity como:Aplicación Android vs Actividad

<intent-filter> 
    <action android:name="android.intent.action.MAIN" /> 
<category android:name="android.intent.category.LAUNCHER" /> 
</intent-filter> 

Sería muy bueno para la determinación del alcance algunos métodos, la estática, de preferencias globales compartidos, etc si podría iniciar mi aplicación usando un Application que luego llama al primer después de configurar prefs, etc., pero no he podido encontrar ningún ejemplo de este patrón de diseño ... cuando pruebo esto en el código, obtengo a ClassCastException:

public class MyApplication extends Application { 
@Override 
    public void onCreate() { 
     super.onCreate(); 

     // do stuff (prefs, etc) 

     // start the initial Activity 
     Intent i = new Intent(this, InitialActivity.class); 
    startActivity(i); 
    } 
} 

InitialActivity.class es de hecho un Activity que funciona bien si configuro que sea MAIN, pero intentar iniciarlo desde MyApplication que se declara MAIN genera el error. Probablemente sea una pregunta muy tonta, pero ¿estoy abordando todo mal?

Gracias,

Paul

+3

¿Quiere decir que estás definiendo MyApplication como una actividad? Eso, de hecho, causaría una ClassCastException. Afortunadamente, Android ya hace por ti lo que quieres hacer, si entiendo correctamente lo que quieres hacer. Solo necesita establecer el nombre de su aplicación en esa ruta y el nombre de MyApplication. Se creará antes de sus Actividades, y estará disponible para todas ellas. De esta manera:

+0

Interesante: ¿cómo accedería a los métodos personalizados de la aplicación desde una de las actividades? –

+1

Desde dentro de su Actividad puede obtener un manejador de la Aplicación de la siguiente manera: getApplicationContext(), el resultado del cual, si está configurado como arriba en su manifiesto, se convertirá en MyApplication. –

Respuesta

19

Puede solucionar este problema mediante el uso de la bandera FLAG_ACTIVITY_NEW_TASK:

Intent intent = new Intent(this, ApplicationActivity.class); 
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
startActivity(intent); 

Esto se debe a que necesita para iniciar nueva tarea cuando se inicia la actividad fuera del contexto de actividad. Pero recomiendo encarecidamente que no se inicie Activity desde la aplicación onCreate().


Android tiene 4 componentes: Actividad, Servicio, ContentProvider y Broadcast.

Cuando Android necesita activar uno de estos componentes desde su aplicación, busca si ya existe un proceso en ejecución con su aplicación. De lo contrario, Android inicia un nuevo proceso, lo inicializa y luego inicializa su instancia de aplicación personalizada. Y luego activa uno de los componentes necesarios.

Ahora, consideremos el próximo escenario: su aplicación declaró el proveedor de contenido en AndroidManifest.xml, y Android está a punto de iniciar su aplicación para que pueda proporcionar algunos datos a otra aplicación en primer plano.

petición Proveedor
  1. contenido se envía
  2. Su solicitud no estaba en funcionamiento, y Android se inicia nuevo proceso para ello.
  3. Se crea su instancia de aplicación personalizada
  4. Application.onCreate().
  5. iniciar una actividad
  6. su proveedor de contenidos recibe solicitar

Alguien sólo quería conectarse a su proveedor de contenido, pero su aplicación se ha iniciado una actividad en su lugar. Lo mismo es cierto para iniciar el servicio de fondo y, a veces, los receptores de difusión.

Y también considere si alguna otra actividad de la aplicación A quería iniciar la actividad X desde su aplicación. Pero en onCreate() comenzaste la actividad Y, y luego X también se inicia con Android. Luego el usuario presiona hacia atrás. ¿Qué debería pasar? Es complicado ...

Las actividades de inicio de ApplicationonCreate pueden dar como resultado una experiencia de usuario bastante extraña. Entonces no lo hagas


ACTUALIZACIÓN: Debido Android garantiza que la solicitud se crea una sola vez y antes de cualquier otro componente, puede utilizar junto código para acceder sola instancia de su aplicación:

public class MyApplication extends Application 
{ 
    private static MyApplication s_instance; 

    public MyApplication() 
    { 
     s_instance = this; 
    } 

    public static MyApplication getApplication() 
    { 
     return s_instance; 
    } 
} 
+0

Excelente, gracias. Entonces, en términos de declarar métodos personalizados en MyApplication que puedo exponer al resto de 'Activity', ¿es esto posible? ¿Cómo puedo acceder a ellos ('getApplication()' no parece hacer el truco) –

+0

He actualizado la respuesta. – inazaruk

+0

Entonces, se accederá a todos los métodos que tengo en MyApplication a los que quiero acceder a través de MyApplication.getApplication(). MyMethod()? –

0

¿Te ha establecido que en la etiqueta se manifiesta la actividad para este fin está empezando (otro además de su principal)?

</activity> 
      <activity android:name=".InitialActivity"       
        android:label="@string/app_name"> 
      <intent-filter> 
       <action android:name="com.package.INITACT" /> <--- this is only name by which you activity can be called. 
       <category android:name="android.intent.category.DEFAULT" /> 
      </intent-filter> 
     </activity> 
Cuestiones relacionadas