Android: ¿Por qué hacer clic en la notificación de intención con backstack destruye Parent MainActivity?

A continuación se muestra mi función sendNotification que se llamará desde un servicio, está funcionando bien creando una notificación y mostrándola en la barra de estado. Pero cuando la aplicación ya se está ejecutando (estoy en MainActivity), haciendo clic en la notificación para abrir ConversActivity, se destruye la MainActivity principal y cuando vuelvo a pulsar el botón de ConversActivity, MainActivity se vuelve a crear. Por favor, ayúdame a evitar este comportamiento cuando la aplicación se está ejecutando (ya sea en primer plano / fondo)

Por cierto, este es el comportamiento correcto cuando la aplicación se muere o no se ejecuta, porque MainActivity se crea desde la backstack, que es correcto. Pero cuando se ejecuta la aplicación, ¿por qué MainActivity se destruye y se vuelve a crear? Esto no es eficiente y causa lentitud en la aplicación debido a la iniciación de la aplicación de la onCreate de MainActivity.

Gracias de antemano Saludos cordiales.

AndroidManifest.xml:

<activity android:name=".View.MainActivity" android:hardwareAccelerated="true" android:windowSoftInputMode="stateHidden" android:launchMode="singleTop" android:label="@string/app_name" android:screenOrientation="portrait" android:theme="@android:style/Theme.Black.NoTitleBar" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".View.ConversActivity" android:label="@string/title_activity_convers" android:parentActivityName=".View.MainActivity" android:screenOrientation="portrait" android:windowSoftInputMode="stateHidden|adjustResize" > <meta-data android:name="android.support.PARENT_ACTIVITY" android:value=".View.MainActivity"/> </activity> 

ConversActivity.java (botón Atrás):

 @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. switch (item.getItemId()) { case android.R.id.home: //onBackPressed(); //finish(); NavUtils.navigateUpFromSameTask(this); return true; case R.id.action_settings: return true; } return super.onOptionsItemSelected(item); } 

 public static void sendNotification(Context context, String dname) { NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); Intent intent = new Intent(context, ConversActivity.class); intent.putExtra("dname", dname); PendingIntent pendingIntent = TaskStackBuilder.create(context) // add all of DetailsActivity's parents to the stack, // followed by DetailsActivity itself .addNextIntentWithParentStack(intent) .getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context) .setSmallIcon(R.drawable.ic_launcher) .setContentTitle("You've got a message!") .setStyle(new NotificationCompat.BigTextStyle().bigText("@" + dname + ": " + msg)) .setContentText("@" + dname + ": " + msg) .setAutoCancel(true) .setVibrate(new long[]{100, 100}) //off-on-off-on-off .setLights(Color.GREEN, 3000, 3000) .setSound(Settings.System.DEFAULT_NOTIFICATION_URI); ; mBuilder.setContentIntent(pendingIntent); mNotificationManager.notify(dname, 0, mBuilder.build()); } 

Mirando el código fuente, parece que TaskStackBuilder añade los siguientes indicadores a la raíz Actividad Intent :

  intents[0].addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK | IntentCompat.FLAG_ACTIVITY_TASK_ON_HOME); 

Si lee la documentación sobre cómo configurar el comportamiento de navegación esperado del usuario para las notificaciones, parece que lo que quieren que haga es hacer que la notificación cree una "tarea nueva" que contendrá la actividad que está iniciando y una copia de seguridad adecuada, Pila para que el usuario será capaz de realizar copias de seguridad de una copia "nueva" de la aplicación en la pantalla HOME. Me temo que el comportamiento estándar de taskAffinity es susceptible de hacer imposible preservar la tarea de su aplicación original y también iniciar otro desde la notificación. Eso no puede ser lo que quieres de todos modos.

Lo que está ocurriendo aquí es que, si su aplicación se está ejecutando y hace clic en la notificación, la tarea existente se está llevando al primer plano, se borra (todas las actividades se terminan / se destruye) y luego se inicia la actividad superior en esta tarea. Su caso ConversActivity ). La pila trasera se configura de modo que si el usuario hace clic en ATRÁS, recreará las actividades anteriores en la pila trasera, una a la vez, hasta que el usuario termine en la pantalla HOME.

Lo anterior debe explicar lo que está sucediendo y por qué.

Para solucionar su problema, sugeriría que haga lo siguiente:

No configure el backstack para la notificación. Simplemente ConversActivity la notificación inicie ConversActivity .

En ConversActivity.onCreate() realice lo siguiente:

 super.onCreate(...); if (isTaskRoot()) { // Started from a Notification and the app is not running, restart the app with back stack // Here create a launch Intent which includes the back stack Intent intent = new Intent(this, ConversActivity.class); // Copy extras from incoming Intent intent.putExtras(getIntent()); // Now launch this activity again and immediately return TaskStackBuilder.create(this) .addNextIntentWithParentStack(intent) .startActivities(); return; } 

Esto solo debería iniciar ConversActivity en la parte superior de la aplicación existente (si está abierta) y lanzarla con la pila posterior correcta si la aplicación no se está ejecutando.

Si su mainactivity no está funcionando que sus datos de la notificación vendrán en mainactivity que usted puede pasar datos de mainactivity a conversactivity.If mainactivity que funciona tha sus datos pasan directamente en conversactivity

  public class MainActivity extends Activity { public static boolean isMainActivityRunning; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); } @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); isMainActivityRunning = true; } @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); isMainActivityRunning = false; } } 

Hacer algún cambio en su PendingIntent

  NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); Intent intent=null; if(!MainActivity.isMainActivityRunning){ intent = new Intent(context, MainActivity.class); } else{ intent = new Intent(context, ConversActivity.class); } intent.putExtra("dname", dname); int requestID = (int) System.currentTimeMillis(); PendingIntent mContentIntent = PendingIntent.getActivity(mContext, requestID , intent , Intent.FILL_IN_ACTION); 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.