活动A启动没有标志的活动B.堆栈现在是A-B,顶部是B. B使用FLAG_ACTIVITY_REORDER_TO_FRONT(唯一标志)启动活动A.我希望这个堆栈现在是B-A。但是,当此时按下后退按钮时,它将返回主屏幕。在这里,我希望将活动B带到前面。再次单击启动器图标后,应用程序将打开,其中B为运行活动,堆栈中没有任何内容。
Launchmode是清单中的标准(默认)。
这是预期的行为吗?我只是不能正确理解它?
编辑:我创建了一个没有混淆因素的测试项目,但仍然看到相同的行为。我只是不理解它,它似乎不是根据文档。
编辑:对我来说,这种行为似乎是框架中的一个BUG,请参阅我对以下答案的评论。我需要一个解决方法。
public class MainActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void onClickBtn(View view)
{
Intent flowIntent = new Intent(this, SecondActivity.class);
startActivity(flowIntent);
}
}
public class SecondActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void onClickBtn(View view)
{
Intent flowIntent = new Intent(this, MainActivity.class);
flowIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(flowIntent);
}
}
清单:
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void onClickBtn(View view)
{
Intent flowIntent = new Intent(this, SecondActivity.class);
startActivity(flowIntent);
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void onClickBtn(View view)
{
Intent flowIntent = new Intent(this, MainActivity.class);
flowIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(flowIntent);
}
答案 0 :(得分:21)
http://code.google.com/p/android/issues/detail?id=63570#c2
谷歌已经确认这是4.4.2的错误
答案 1 :(得分:8)
首先,让我们先说you're right!
但是如果我的逻辑是正确的,那么当你REORDER
到你的主Activity
(Launcher
Activity
)时会发生什么,意图被设置为背压将返回Launcher
。
作为实验,尝试添加Activity
C并尝试将REORDER
B从C开始到前面。
那就是:
A-> B-> C ... A-> C-> B
如果订单对您非常重要,您可能需要覆盖Activity.onNewIntent()方法。
@Override
protected void onNewIntent(Intent intent) {
}
答案 2 :(得分:7)
我找到了这个错误的简单解决方法。
覆盖onNewIntent并完成任何可能重新排序到前台活动的功能,如下所示,只是不完全测试,如果您发现此解决方法有任何问题,请通过ricotta.zhang@myriadgroup.com与我联系
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if ((intent.getFlags() | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) > 0) {
mIsRestoredToTop = true;
}
}
@Override
public void finish() {
super.finish();
if (android.os.Build.VERSION.SDK_INT >= 19 && !isTaskRoot() && mIsRestoredToTop) {
// 4.4.2 platform issues for FLAG_ACTIVITY_REORDER_TO_FRONT,
// reordered activity back press will go to home unexpectly,
// Workaround: move reordered activity current task to front when it's finished.
ActivityManager tasksManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
tasksManager.moveTaskToFront(getTaskId(), ActivityManager.MOVE_TASK_NO_USER_ACTION);
}
}
答案 3 :(得分:2)
我根本找不到这个问题。 Here is the project I have created。
我刚刚用overFinish()方法来检查哪个Activity已关闭。
答案 4 :(得分:1)
我也遇到了这个错误,并决定我可能需要解决它。至少在我的情况下,似乎可以通过为版本4.4.2提供自定义后台堆栈实现。这绝不是漂亮的,并且可能无法在所有情况下都有效,但它确实保存了我和基于DrawerLayout
的导航。
首先,我有一个NavigationDrawerActivity
作为所有其他活动扩展的类。在那里,我有一个静态Stack
用于被调用的类以及可以从导航抽屉访问的类数组。 addClassToStack
方法是公共的,因此除了抽屉之外的其他导航方式也可以使用堆栈。注意如何首先删除要添加到堆栈中的类(如果存在),以便我们获得与重订单到前端标志通常提供的相同的功能。我用版本检查包围了hacky代码,以便只在必要时才使用hack。
public class NavigationDrawerActivity extends Activity {
...
private static Stack<Class<?>> classes = new Stack<Class<?>>();
private Class<?>[] activity_classes;
...
public static void addClassToStack(Class<?> to_add) {
if (android.os.Build.VERSION.RELEASE.equals("4.4.2")) {
classes.remove(to_add);
classes.push(to_add);
}
}
...
接下来是导航抽屉的监听器类。抽屉上的按钮位于ListView
,因此每次用户想要去某处时,都会调用此处的onItemClick
。这里唯一的“hacky”是调用addClassToStack
将新活动添加为后台堆栈的顶部。
private class DrawerItemClickListener implements ListView.OnItemClickListener {
private Intent i;
@Override
public void onItemClick(AdapterView<?> parent, View v, int pos, long id) {
i = new Intent(NavDrawerActivity.this, activity_classes[pos]);
addClassToStack(activity_classes[pos]);
i.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
nav_drawer.closeDrawers();
startActivity(i);
}
}
解决方法的最后一部分是覆盖onKeyDown
方法,如果在Android 4.4.2上按下后退按钮(我们超出导航中的第一个活动),则要打开的活动从我们的自定义后台堆栈中获取并直接调用。请注意,堆栈中最顶层的项目始终是当前活动,因此我们需要摆脱它并使用第二个项目作为目标。还要注意我在返回第一个活动时如何清除正式任务历史记录。这是必需的,因为否则,在再次按下并返回主屏幕后,下次访问该应用程序时,它会直接进入官方后台堆栈的顶部。
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
boolean handled = false;
if (keyCode == KeyEvent.KEYCODE_BACK &&
android.os.Build.VERSION.RELEASE.equals("4.4.2") &&
classes.size() > 1) {
classes.pop();
Intent prev = new Intent(this, classes.peek());
if (classes.size() == 1) {
prev.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
} else {
prev.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
}
startActivity(prev);
handled = true;
}
if (!handled) {
return super.onKeyDown(keyCode, event);
} else {
return true;
}
}
}
唯一剩下的(这里没有显示)是将初始活动(应用程序启动时打开的活动)添加到适当位置的后堆栈中。在我的应用程序中,我有一个单独的开始屏幕,无法通过导航抽屉访问,因此我可以从该活动的onCreate中调用NavigationDrawerActivity.addClassToStack(StartScreenActivity.class)
。对于其他结构,您可能会做一些不同的事情,以确保初始活动仅作为第一个项目添加到堆栈中。
现在,这是一个黑客,我还没有彻底测试过,但它似乎也适用于Nexus 4(4.4.2)和Nexus S(卡在4.1上)。因此,如果你尝试做这样的事情并且它不起作用,不要生气但是让我知道。 :)
答案 5 :(得分:0)
我发现这个问题发生在S7 7.0操作系统上,当使用Flag Intent.FLAG_ACTIVITY_REORDER_TO_FRONT设置活动并且此活动结束时,用户将进入设备的主屏幕。
我为此修好了 - 删除了标志Intent.FLAG_ACTIVITY_REORDER_TO_FRONT并添加了noHistory = true
这样新的活动实例就会被推送到堆栈,因为noHistory为true,旧的实例已经是堆栈的一部分被破坏了。