-
前言
最近几天刚刚跳槽完毕。在家歇了快一个月了。重现开始上班后,还真有点不适应。上班实在是太辛苦了, 还是坐地铁13号线。但是变成反向乘坐了。 昨天才拿到的电脑,连代码还没看呢,就接到了新的任务:解决一个bug。 好了,废话不多说,先描述一下bug情况。
- BUG描述
- DEMO实例
public class TestActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void a(View view) {
//启动掉转到Test2
Intent intent = new Intent(TestActivity.this, Test2Activity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP
| Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent contentIntent = PendingIntent.getActivity(TestActivity.this, 0,
intent,PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new Notification(R.drawable.icon, "ticker", System.currentTimeMillis());
notification.setLatestEventInfo(TestActivity.this, "title", "text", contentIntent);
NotificationManager notificationMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationMgr.notify(1000, notification);
}
public void b(View view) {
//掉转到Test3
Intent intent = new Intent(TestActivity.this, Test3Activity.class);
startActivity(intent);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK) System.exit(0);
return super.onKeyDown(keyCode, event);
}
}
public class Test2Activity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void a(View view) {}
public void b(View view) {
//掉转到Test3
Intent intent = new Intent(Test2Activity.this, Test3Activity.class);
startActivity(intent);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK) System.exit(0);
return super.onKeyDown(keyCode, event);
}
}
- 重现操作流程
- 深入分析
同一个application里面,每个activity的taskAffinity默认都是一样的。也就是说楼主代码里的ActivityTwo和ActivityMain的taskAffinity是一样的,假设这个taskAffinity是"com.test"。ActivityMain启动时,新建了一个task,这个task的taskAffinity就是"com.test"。ActivityTwo具有singleTask属性,启动时,会先寻找是否有相同taskAffinity的task存在,没有的话,才会启动一个新的task,但是这时发现已经有一个task存在了,它的taskAffinity也是"com.test",就不会启动新的task了,而是把ActivityTwo放入这个task的栈中,这时候task id是一样的。
所以使用singleTask时,要想新建一个task,就得保证taskAffinity值不同,比如设置ActivityTwo的taskAffinity="com.test2",这时再运行楼主的代码,就会发现task id不一样了。
以上是两个activity在同一个application中的情况。如果在某个application调用其他application里声明的singleTask模式的Activity呢。taskAffinity的值默认是包名,两个application一般包名都不一样,如果taskAffinity都是默认的话,它会重新创建一个Task,然后将该Activity实例化并压入task的栈。
- 解决办法:
intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
//如果activity在task存在,将Activity之上的所有Activity结束掉
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
//默认的跳转类型,将Activity放到一个新的Task中
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//如果Activity已经运行到了Task,再次跳转不会在运行这个Activity
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);