Android:为什么用backstack点击意图通知会破坏父MainActivity?

hem*_*mlk 6 android android-intent android-activity android-navigation

下面是我的sendNotification函数,它将从一个服务调用,它正常工作创建一个通知并在状态栏上显示它.但是当应用程序已经运行时(我在MainActivity中),单击通知以打开ConversActivity,主MainActivity将被销毁,当我从ConversActivity按下后退按钮时,将重新创建MainActivity.当应用程序运行时(请在前/后),请帮助我避免此行为

顺便说一句,这是应用程序被杀或未运行时的正确行为,因为从Backstack创建了MainActivity,这是正确的.但是当应用程序运行时,为什么MainActivity会被销毁并重新创建?由于MainActivity的onCreate启动了app,因此效率不高并导致应用程序运行缓慢.

在此先感谢和最诚挚的问候.

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>
Run Code Online (Sandbox Code Playgroud)

-

ConversActivity.java(后退按钮):

@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);
}
Run Code Online (Sandbox Code Playgroud)

-

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());
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*ser 13

查看源代码,看起来像TaskStackBuilder将以下标志添加到根Activity Intent:

    intents[0].addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
            IntentCompat.FLAG_ACTIVITY_CLEAR_TASK |
            IntentCompat.FLAG_ACTIVITY_TASK_ON_HOME);
Run Code Online (Sandbox Code Playgroud)

如果您阅读有关如何为通知设置用户预期导航行为的文档,他们希望您做的就是让通知创建一个"新任务",其中包含您要启动的活动和适当的后退堆栈,以便用户可以通过应用程序的"新"副本备份回HOME屏幕.我担心标准行为taskAffinity会导致无法保留原始应用程序的任务,也无法从通知中启动另一个任务.无论如何,这可能不是你想要的.

这里发生的是,如果您的应用程序正在运行并且您单击通知,则现有任务将被置于前台,清除(所有活动已完成/销毁),然后最顶层的活动将启动到此任务中(在你的情况ConversActivity).然后设置后向堆栈,以便在用户单击BACK时,它将一次一个地重新创建后堆栈中的先前活动,直到用户在HOME屏幕结束.

以上应该解释发生了什么以及为什么.

为了解决您的问题,我建议您执行以下操作:

不要为通知设置后台堆叠.只需启动通知即可ConversActivity.

ConversActivity.onCreate()做到以下几点:

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;
}
Run Code Online (Sandbox Code Playgroud)

这应该只是ConversActivity在您现有的应用程序之上启动(如果它是打开的),并且如果您的应用程序没有运行,应该使用正确的后台启动它.