问题来源于2个应用的相互跳转,代码如下.
Intent intent = new Intent();
intent.setAction("com.qylk.call.main");
startActivity(intent);
相当的简单,看似没有任何问题,其实是有一点问题的.我们假如是A应用跳转到B应用,当A应用跳转到B应用时,按下HOME键,然后在点击A应用,问题就出来了,我的天,出现在我们面前居然是B应用.出了鬼了,我明明点的是A应用,怎么会出现B应用.其实这个问题也非常简单,加上一个独立的栈就完事了.
Intent intent = new Intent();
intent.setAction("com.qylk.call.main");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
这样就完事.其实我今天讲的重点不在这.看下面代码.
Intent intent = getPackageManager().getLaunchIntentForPackage("com.tcl.navigator.b");
startActivity(intent);
用包名跳转是完全没的问题的,也不会出现上面的那种BUG.奇怪的是,我们这没有加上独立的栈,为什么也不会出现问题呢?Android手机的Launcher都是用的包名跳转的.下面就去看看,到底它把Intent怎么了.
getLaunchIntentForPackage()方法在PackageMnaager里面,我们看看它到底做了什么.
fuck!居然是抽象的,坑死人…没得办法了,继续找.
看看PackageManager的子类.
ok,找到了,赶快进去看看.
日了狗,明显不对.其实这个是工具的一个小bug,没有把它的子类全部列举出来,大写的坑…
直接告诉你们算了,免得找半天.ApplicationPackageManager也实现了PackageManager,我们进去看看这个对不对.
我去,怪不得没有列举出来,原来是隐藏起来了.再看看它怎么重写的getLaunchIntentForPackage()方法
@Override
public Intent getLaunchIntentForPackage(String packageName) {
// First see if the package has an INFO activity; the existence of
// such an activity is implied to be the desired front-door for the
// overall package (such as if it has multiple launcher entries).
Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
intentToResolve.addCategory(Intent.CATEGORY_INFO);
intentToResolve.setPackage(packageName);
List<ResolveInfo> ris = queryIntentActivities(intentToResolve, 0);
// Otherwise, try to find a main launcher activity.
if (ris == null || ris.size() <= 0) {
// reuse the intent instance
intentToResolve.removeCategory(Intent.CATEGORY_INFO);
intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
intentToResolve.setPackage(packageName);
ris = queryIntentActivities(intentToResolve, 0);
}
if (ris == null || ris.size() <= 0) {
return null;
}
Intent intent = new Intent(intentToResolve);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setClassName(ris.get(0).activityInfo.packageName,
ris.get(0).activityInfo.name);
return intent;
}
看返回值,返回一个intent.
Intent intent = getPackageManager().getLaunchIntentForPackage("com.tcl.navigator.b");
startActivity(intent);
我们调用这个方法也是得到一个intent,然后用这个intent跳转.在看看它对这个intent做了什么.看倒数第4行,看到了吧
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
那就对上了,其实它内部早就跟你加上了独立的栈.
所以以后希望大家不要写类似这样的代码
Intent intent = getPackageManager().getLaunchIntentForPackage("com.tcl.navigator.b");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
当然,这样写也没得错,但是总感觉哪里不对.赶快看看自己的项目有没有这样的写的,快去改过来吧.