下面是我的sendNotification函数,将从服务中调用该函数,它可以很好地创建通知并将其显示在状态栏上。但是,当应用程序已经运行时(我在MainActivity上),单击通知以打开ConversActivity,父MainActivity被破坏,并且当我从ConversActivity按下返回按钮时,将重新创建MainActivity。请帮助我避免在应用程序运行时出现这种情况(在前台/后台运行)
顺便说一句,当应用程序被终止或未运行时,这是正确的行为,因为从后台创建了coz MainActivity,这是正确的。但是,当应用程序运行时,为什么要销毁并重新创建MainActivity?由于MainActivity的onCreate启动应用程序,因此效率不高,并导致应用程序运行缓慢。
在此先感谢您和最诚挚的问候。
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(后退按钮):
@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());
}
最佳答案
查看源代码,看来TaskStackBuilder
向根 Activity Intent
添加了以下标志:
intents[0].addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
IntentCompat.FLAG_ACTIVITY_CLEAR_TASK |
IntentCompat.FLAG_ACTIVITY_TASK_ON_HOME);
如果您阅读有关如何设置用户预期的Notifications导航行为的documentation,似乎他们想要您做的就是让Notification创建一个“新任务”,其中将包含您正在启动的Activity和一个适当的back-堆栈,以便用户能够通过应用程序的"new"副本备份回到HOME屏幕。恐怕
taskAffinity
的标准行为容易导致无法保留原始应用程序的任务,也无法从Notification(通知)启动另一个任务。无论如何,那可能不是您想要的。这里发生的是,如果您的应用程序正在运行并且您单击通知,则将现有任务置于前台,将其清除(所有 Activity 均已完成/销毁),然后将最顶层的 Activity 启动到该任务中(在您的案例
ConversActivity
)。然后设置后退堆栈,以便如果用户单击“后退”,它将一次在后退堆栈中重新创建以前的“ Activity ”,直到用户最终到达“主页”屏幕为止。上面应该解释发生了什么以及为什么。
为了解决您的问题,建议您执行以下操作:
不要为通知设置后台程序。只需将Notification启动
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;
}
这应该只是在现有应用程序的顶部启动
ConversActivity
(如果已打开),并且如果您的应用程序未运行,则应使用正确的后台堆栈启动它。