场景
- 新闻类App有新内容推送过来时,从Notification打开详情页面,此时按返回键,返回的是新闻列表页(主页面)。
- 邮件类型的App,从邮件列表进入到详情,并从详情页面进入到更深的子页面,此时返回键是根据用户浏览习惯返回,顶部导航(ActionBar)返回的是邮件列表页。
实现新闻的效果
PendingIntent携带任务栈信息,配置xml,DetailsActivity配置parentActivity;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"> <application android:name=".MyApplication"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".DetailsActivity" android:parentActivityName=".MainActivity"> <meta-data android:name="android.support.PARENT_ACTIVITY" android:value=".MainActivity" /> </activity>
<service android:name=".MyService" android:enabled="true" android:exported="true"></service> </application> </manifest>
|
- Service里开启一个Notification(just demo)
原理是利用TaskStackBuilder来返回PendingIntent,这样在startActivity的时候会构建Activity栈
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class MyService extends Service { @Override public void onCreate() { super.onCreate(); Intent detailActivity = new Intent(this, DetailsActivity.class); TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); stackBuilder.addNextIntentWithParentStack(detailActivity); PendingIntent pendingIntent = stackBuilder .getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this); builder.setContentText("测试内容"). setContentIntent(pendingIntent). setAutoCancel(true); NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); manager.notify(1, builder.build()); } }
|
结果
- Notification打开DetailsActivity的时候,此时MainActivity已经销毁,只剩下Service
05-17 16:07:42.314 4946-4946/com.asura.justfortest I/TAG: onCreate: DetailsActivity
按下返回键的时候
05-17 16:07:46.916 4946-4946/com.asura.justfortest I/TAG: onCreate: MainActivity
好处是本应用没有开启,这种方式返回时可以带到主页去
- 当MainActivity和DetailsActivity都存在的情况下,使用这种方式会将app现有的Task栈
取代
,即现有的所有Activity会销毁,即使设置launchMode为singleTask也没用
- 对于不想销毁现有的任务栈的情况,notification配intent时就不要配置TaskStack,针对DetailsActivity可以覆盖返回键,当Task栈为空的时候,启动带Stack的Intent,如果栈不为空,直接finish掉.
顶部导航或者返回键回到父页面(中间的会被销毁)
覆盖onOptionsItemSelected,onBackPress();其中,调用NavUtils.getParentActivityIntent()方法可以获取到跳转至父Activity的Intent,然后如果父Activity和当前Activity是在同一个Task中的,则直接调用navigateUpTo()方法进行跳转,如果不是在同一个Task中的,则需要借助TaskStackBuilder来创建一个新的Task
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: goToMain(); return true; } } @Override public void onBackPressed() { goToMain(); } private void goToMain() { Intent upIntent = NavUtils.getParentActivityIntent(this); if (NavUtils.shouldUpRecreateTask(this, upIntent)) { TaskStackBuilder.create(this) .addNextIntentWithParentStack(upIntent) .startActivities(); } else { upIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK); NavUtils.navigateUpTo(this, upIntent); } }
|
参考