7

我正在尝试根据以下内容实现导航:http: //developer.android.com/training/implementing-navigation/ancestral.html

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    // Respond to the action bar's Up/Home button
    case android.R.id.home:
        Intent upIntent = NavUtils.getParentActivityIntent(this);
        if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
            // This activity is NOT part of this app's task, so create a new task
            // when navigating up, with a synthesized back stack.
            TaskStackBuilder.create(this)
                    // Add all of this activity's parents to the back stack
                    .addNextIntentWithParentStack(upIntent)
                    // Navigate up to the closest parent
                    .startActivities();
        } else {
            // This activity is part of this app's task, so simply
            // navigate up to the logical parent activity.
            NavUtils.navigateUpTo(this, upIntent);
        }
        return true;
    }
    return super.onOptionsItemSelected(item);
}

if (NavUtils.shouldUpRecreateTask(this, upIntent)) {总是返回 FALSE。

这段代码有什么用?在哪些情况下它会返回 true?

4

2 回答 2

4

在 pre-Jelly Bean 设备上,根据NavUtils 的源代码shouldUpRecreateTask是:

public boolean shouldUpRecreateTask(Activity activity, Intent targetIntent) {
    String action = activity.getIntent().getAction();
    return action != null && !action.equals(Intent.ACTION_MAIN);
}

它使用Activity' 的操作(即ACTION_VIEW等)来确定这是否Activity是从外部源启动的。在 Jelly Bean+ 设备上,它使用Activity.shouldUpRecreateTask源代码):

public boolean shouldUpRecreateTask(Intent targetIntent) {
    try {
        PackageManager pm = getPackageManager();
        ComponentName cn = targetIntent.getComponent();
        if (cn == null) {
            cn = targetIntent.resolveActivity(pm);
        }
        ActivityInfo info = pm.getActivityInfo(cn, 0);
        if (info.taskAffinity == null) {
            return false;
        }
        return !ActivityManagerNative.getDefault()
                .targetTaskAffinityMatchesActivity(mToken, info.taskAffinity);
    } catch (RemoteException e) {
        return false;
    } catch (NameNotFoundException e) {
        return false;
    }
}

它使用任务关联性来确定给定Activity的关联性是否与启动它的关联性相同(即,如果 Gmail 启动您Activity的关联性,它将获得 Gmail 的关联性,而不是它自己的关联性)。

NavUtils.navigateUpTo,在所有情况下,都会启动一个 Activity。如果它没有启动适当的Activity,那么您可能需要查看您使用的启动模式并提供有关它不工作的平台版本的详细信息。

于 2013-07-01T02:04:22.630 回答
0

我通过使用 ActivityManager 并检查 backStack 条目来解决它。

希望对大家有用。

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:

            ActivityManager am = (ActivityManager) getApplicationContext().getSystemService(getApplicationContext().ACTIVITY_SERVICE);
            List<RunningTaskInfo> runningTaskInfoList =  am.getRunningTasks(10);
            List<String> backStack = new ArrayList<String>();
            Iterator<RunningTaskInfo> itr = runningTaskInfoList.iterator();
            while(itr.hasNext()){
                RunningTaskInfo runningTaskInfo = (RunningTaskInfo)itr.next();
                String topActivity = runningTaskInfo.topActivity.getShortClassName();
                backStack.add(topActivity.trim());
            }
            if(backStack!=null){
                if(backStack.get(1).equals(".MainActivity")){
                    moveTaskToBack(true); // or finish() if you want to finish it. I don't.
                } else {
                    Intent intent = new Intent(this, MainActivity.class);
                    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    startActivity(intent);
                    finish();
                }
            }

        break;  
    }
}

我需要使用:

<uses-permission android:name="android.permission.GET_TASKS" />

在我的清单中。

它完美地工作,虽然它不是我想要的解决方案。不幸的是,android仍然缺乏高级的内置方法来实现简单的事情,我们都必须找到一切的方法。

于 2013-07-01T16:23:27.027 回答