Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android NavUtils.navigateUpTo()不启动任何活动_Android_Android Activity_Android Lifecycle - Fatal编程技术网

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
  • 向上压
  • 我的应用程序关闭,就像按back键一样
  • 我调试了代码,发现
    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);
        }
    }