Android NavUtils.navigateUpTo()不启动任何活动
我有两项活动Android NavUtils.navigateUpTo()不启动任何活动,android,android-activity,android-lifecycle,Android,Android Activity,Android Lifecycle,我有两项活动 main活动 DeepLinkActivity 我将所有内容设置为使用NavUtils向上导航,就像建议的那样 我想要实现的是: 通过深度链接启动DeepLinkActivity 向上压 转到main活动 只要在最近的应用程序中有我的应用程序的任何任务,一切都很好 但是,当我从最近的应用中刷走我的应用时,其行为如下: 从最近的应用中刷走我的应用 通过深度链接启动DeepLinkActivity 向上压 我的应用程序关闭,就像按back键一样 我调试了代码,发现NavUtils.
main活动
DeepLinkActivity
NavUtils
向上导航,就像建议的那样
我想要实现的是:
DeepLinkActivity
main活动
DeepLinkActivity
NavUtils.shouldUpRecreateTask()
返回false
。
upIntent
将一切设置为正常,如我的组件
设置。
但是,NavUtils.navigateUpTo()
的行为就像调用finish()
。
没有日志语句,什么都没有
有什么想法,怎么解决
AndroidManifest.xml
<activity
android:name=".DeepLinkActivity"
android:parentActivityName="my.package.MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="my.package.MainActivity"/>
<intent-filter>
<!-- Some intent filter -->
</intent-filter>
</activity>
-----编辑-----
我意识到一些谷歌应用程序也是以同样的方式被破坏的。如果您从搜索跳转到通讯录,请在AB中按up,您将在主屏幕而不是通讯录应用程序中找到自己。(API19/cm11)试试这个:
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Intent upIntent = NavUtils.getParentActivityIntent(this);
if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
// create new task
TaskStackBuilder.create(this).addNextIntentWithParentStack(upIntent)
.startActivities();
} else {
// Stay in same task
NavUtils.navigateUpTo(this, upIntent);
}
break;
default:
return super.onOptionsItemSelected(item);
}
return true;
}
这对我也不管用。所以我这样处理:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
我的MainActivity在android清单中标记为singleTask
android:launchMode="singleTask"
它看起来像是
NavUtils.shouldUpRecreateTask(this,upIntent)
没有为这种特殊情况做好准备
我当前的解决方法是检查活动
是否有深度链接,并强制为此类情况创建新的任务堆栈
在我的例子中,我在内部传递EXTRA
s中的对象。
但是如果活动
是通过跟踪特定URL的链接或触摸NFC感知设备从外部启动的,则会设置操作
和Uri
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Intent upIntent = NavUtils.getParentActivityIntent(this);
if (NavUtils.shouldUpRecreateTask(this, upIntent)
|| getIntent().getAction() != null) { // deep linked: force new stack
// create new task
TaskStackBuilder.create(this).addNextIntentWithParentStack(upIntent)
.startActivities();
} else {
// Stay in same task
NavUtils.navigateUpTo(this, upIntent);
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}
我认为那个方法被窃听了。我已经阅读了支持库源代码,并且该方法检查了intent的操作。它只在您的应用程序之前创建时起作用。如您所述,如果您从应用程序预览中删除它,shouldUp方法将停止工作 我已经用自己的“shouldUpRecreateTask”解决了这个问题。当我收到直接创建活动(如您的行为)的通知时,我会从我的BroadCastReceiver发送一个intent内的自定义操作。然后,在我的方法中,我做下一件事:
private final boolean shouldUpRecreateTask(Activity from){
String action = from.getIntent().getAction();
return action != null && action.equals(com.xxxxxx.activities.Intent.FROM_NOTIFICATION);
}
if (shouldUpRecreateTask(this)) {
TaskStackBuilder.create(this)
.addNextIntentWithParentStack(upIntent)
.startActivities();
} else {
fillUpIntentWithExtras(upIntent);
NavUtils.navigateUpTo(this, upIntent);
}
如果从通知转到活动,则在创建通知时必须创建堆栈,请签出以下答案:我发现以下方法对我有效。如果该活动与另一个活动或通知深度链接,则在向上导航时将创建堆栈,否则,这些活动将被置于最前面
case android.R.id.home:
Intent upIntent = NavUtils.getParentActivityIntent(this);
upIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(upIntent);
finish();
return true;
如果你有
android:parentActivityName="parent.activity"
在您的清单中,您是否使用了:
+public boolean navigateUpTo(IBinder令牌、Intent destinent、int resultCode、,
+意向结果(数据){
+ComponentName dest=destinent.getComponent();
+
+已同步(此){
+ActivityRecord srec=ActivityRecord.forToken(令牌);
+ArrayList history=srec.stack.mHistory;
+final int start=history.indexOf(srec);
+如果(开始<0){
+//当前活动不在历史堆栈中;不执行任何操作。
+返回false;
+ }
+int finishTo=start-1;
+ActivityRecord父项=null;
+布尔值FoundParentTask=false;
+如果(dest!=null){
+TaskRecord tr=srec.task;
+对于(int i=start-1;i>=0;i--){
+ActivityRecord r=历史记录。获取(i);
+如果(tr!=r.task){
+//在同一任务中找不到父任务;请在该任务上方的任务处停止。
+//(当前任务的根;应用程序内“主”行为)
+//始终至少完成当前活动。
+finishTo=Math.min(start-1,i+1);
+父项=历史记录.get(finishTo);
+中断;
+}else if(r.info.packageName.equals(dest.getPackageName())&&
+r.info.name.equals(dest.getClassName()){
+finishTo=i;
+父代=r;
+FoundParentAsk=true;
+中断;
+ }
+ }
+ }
+
+如果(mController!=null){
+ActivityRecord next=mMainStack.topRunningActivityLocked(令牌,0);
+如果(下一步!=null){
+//询问观察者是否允许这样做
+布尔恢复OK=true;
+试一试{
+resumeOK=mController.activityResuming(next.packageName);
+}catch(远程异常e){
+mController=null;
+ }
+
+如果(!resumeOK){
+返回false;
+ }
+ }
+ }
+最终长origId=活页夹.clearCallingIdentity();
+对于(int i=start;i>finishTo;i--){
+ActivityRecord r=历史记录。获取(i);
+mMainStack.requestFinishActivityLocked(r.appToken、resultCode、resultData、,
+“向上导航”);
+//仅返回为完成的第一个活动提供的结果
+resultCode=Activity.RESULT\u已取消;
+resultData=null;
+ }
+
+if(parent!=null&&foundParentInTask){
+final int parentLaunchMode=parent.info.launchMode;
+最终目的地
android:parentActivityName="parent.activity"
+ public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
+ Intent resultData) {
+ ComponentName dest = destIntent.getComponent();
+
+ synchronized (this) {
+ ActivityRecord srec = ActivityRecord.forToken(token);
+ ArrayList<ActivityRecord> history = srec.stack.mHistory;
+ final int start = history.indexOf(srec);
+ if (start < 0) {
+ // Current activity is not in history stack; do nothing.
+ return false;
+ }
+ int finishTo = start - 1;
+ ActivityRecord parent = null;
+ boolean foundParentInTask = false;
+ if (dest != null) {
+ TaskRecord tr = srec.task;
+ for (int i = start - 1; i >= 0; i--) {
+ ActivityRecord r = history.get(i);
+ if (tr != r.task) {
+ // Couldn't find parent in the same task; stop at the one above this.
+ // (Root of current task; in-app "home" behavior)
+ // Always at least finish the current activity.
+ finishTo = Math.min(start - 1, i + 1);
+ parent = history.get(finishTo);
+ break;
+ } else if (r.info.packageName.equals(dest.getPackageName()) &&
+ r.info.name.equals(dest.getClassName())) {
+ finishTo = i;
+ parent = r;
+ foundParentInTask = true;
+ break;
+ }
+ }
+ }
+
+ if (mController != null) {
+ ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
+ if (next != null) {
+ // ask watcher if this is allowed
+ boolean resumeOK = true;
+ try {
+ resumeOK = mController.activityResuming(next.packageName);
+ } catch (RemoteException e) {
+ mController = null;
+ }
+
+ if (!resumeOK) {
+ return false;
+ }
+ }
+ }
+ final long origId = Binder.clearCallingIdentity();
+ for (int i = start; i > finishTo; i--) {
+ ActivityRecord r = history.get(i);
+ mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
+ "navigate-up");
+ // Only return the supplied result for the first activity finished
+ resultCode = Activity.RESULT_CANCELED;
+ resultData = null;
+ }
+
+ if (parent != null && foundParentInTask) {
+ final int parentLaunchMode = parent.info.launchMode;
+ final int destIntentFlags = destIntent.getFlags();
+ if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
+ parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
+ parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
+ (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
+ parent.deliverNewIntentLocked(srec.app.uid, destIntent);
+ } else {
+ try {
+ ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
+ destIntent.getComponent(), 0, UserId.getCallingUserId());
+ int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
+ null, aInfo, parent.appToken, null,
+ 0, -1, parent.launchedFromUid, 0, null, true, null);
+ foundParentInTask = res == ActivityManager.START_SUCCESS;
+ } catch (RemoteException e) {
+ foundParentInTask = false;
+ }
+ mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
+ resultData, "navigate-up");
+ }
+ }
+ Binder.restoreCallingIdentity(origId);
+ return foundParentInTask;
+ }
+ }
public void navigateUp() {
final Intent upIntent = NavUtils.getParentActivityIntent(this);
if (NavUtils.shouldUpRecreateTask(this, upIntent) || isTaskRoot()) {
Log.v(logTag, "Recreate back stack");
TaskStackBuilder.create(this).addNextIntentWithParentStack(upIntent).startActivities();
} else {
NavUtils.navigateUpTo(this, upIntent);
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Intent upIntent = NavUtils.getParentActivityIntent(this);
if (NavUtils.shouldUpRecreateTask(this, upIntent) || isTaskRoot()) {
TaskStackBuilder.create(this).addNextIntentWithParentStack(upIntent)
.startActivities();
} else {
finish();
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}