Android:清除活动堆栈

时间:2011-08-16 08:16:29

标签: android android-activity stack

我在我的应用程序中有几个活动。并且流程非常复杂。当我单击Logout应用程序naviagates登录屏幕时,用户可以通过取消按钮退出(调用system.exit(0)

当我退出或返回按钮时,系统从堆栈调用一个活动:(当我到达登录界面时,如何清除堆栈中的所有活动?调用finish()是不实际的,因为有太多的活动和某些活动在活动时不应关闭,例如本地相机调用活动。

validateuser logoutuser = new validateuser();
logoutuser.logOut();
Intent loginscreen = new Intent(homepage.this, Login2.class);
(homepage.this).finish();
loginscreen.setFlags( Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(loginscreen);

11 个答案:

答案 0 :(得分:298)

大多数人都错了。如果要关闭现有的活动堆栈而不管其中的内容是什么并创建新的根,正确的标志集如下:

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

From the doc

  

public static final int FLAG_ACTIVITY_CLEAR_TASK
  在API级别11中添加

     

如果在Intent中设置传递给   Context.startActivity(),此标志将导致任何现有任务   将与之前要清除的活动相关联   活动开始了。也就是说,活动成为一个新的根   否则为空任务,任何旧活动都已完成。这个可以   只能与FLAG_ACTIVITY_NEW_TASK一起使用。

答案 1 :(得分:29)

当您在上次活动中致电startActivity时,您可以随时使用

  

Intent.FLAG_ACTIVITY_CLEAR_TOP

作为该意图的旗帜。

详细了解国旗here

答案 2 :(得分:16)

这是一个简单的辅助方法,用于启动新活动作为新的顶级活动,从API级别4到当前版本17开始工作:

static void startNewMainActivity(Activity currentActivity, Class<? extends Activity> newTopActivityClass) {
    Intent intent = new Intent(currentActivity, newTopActivityClass);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
        intent.addFlags(0x8000); // equal to Intent.FLAG_ACTIVITY_CLEAR_TASK which is only available from API level 11
    currentActivity.startActivity(intent);
}

从您当前的活动中调用它:

startNewMainActivity(this, MainActivity.class);

答案 3 :(得分:6)

通过以下代码

清除活动后台

Intent intent = new Intent(Your_Current_Activity.this, Your_Destination_Activity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK |Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

完成

答案 4 :(得分:4)

就我而言,LoginActivity也已关闭。结果,

Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK

没有帮助。

但是,设置

Intent.FLAG_ACTIVITY_NEW_TASK

帮助了我。

答案 5 :(得分:4)

Intent intent = new Intent(LoginActivity.this, Home.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);  //It is use to finish current activity
startActivity(intent);
this.finish();

答案 6 :(得分:3)

这个决定很好:

<?php
//Create start of table:
$table = '<table><tbody>';

//Fetch rows:
while ($row = mysqli_fetch_assoc($result)) {

    //append to the table:
    $table .= '<tr><td>' . $row['id'] . '</td>' .
            '<td>' . $row['product_name'] . '</td>' .
            '<td>' . $row['visible'] .   //You forgot the " under here
            '<td><a href="modify.php?id=' . $row['id'] . '">Modify</a>' .
            '</td></tr>';
}

//Append end of table:
$table .= '</tbody></table>';

//print table:
print $table;

但是新活动推出很长时间,你会看到白色屏幕。如果这很关键,那么请使用此解决方法:

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

如何使用它:

public class BaseActivity extends AppCompatActivity {

    private static final String ACTION_FINISH = "action_finish";

    private BroadcastReceiver finisBroadcastReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        registerReceiver(finisBroadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                finish();
            }
        }, new IntentFilter(ACTION_FINISH));
    }

    public void clearBackStack() {
        sendBroadcast(new Intent(ACTION_FINISH));
    }

    @Override
    protected void onDestroy() {
        unregisterReceiver(finisBroadcastReceiver);
        super.onDestroy();
    }
}

缺点:必须在堆栈上关闭的所有活动必须扩展BaseActivity

答案 7 :(得分:2)

我注意到您要求的解决方案不依赖finish(),但我想知道这是否有帮助。

我跟踪是否使用静态类变量引发退出标志,该变量在整个应用程序生命周期中存活。在每个相关活动的onResume()中,使用

@Override
public void onResume() {
    super.onResume();
    if (ExitHelper.isExitFlagRaised) {
        this.finish();
    }
}

ExitHelper类

public class ExitHelper {
    public static boolean isExitFlagRaised = false;
}

假设在mainActivity中,用户按下按钮退出 - 您可以设置ExitHelper.isExitFlagRaised = true;然后finish()。此后,自动恢复的其他相关活动也将完成。

答案 8 :(得分:1)

对于Xamarin开发人员,您可以使用:

intent.SetFlags(ActivityFlags.NewTask | ActivityFlags.ClearTask);

答案 9 :(得分:1)

使用Kotlin:

您可以使用setter方法直接设置标志。在Kotlin中,or是Java的replacement按位或|

intent.flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK

如果您打算定期使用此功能,请创建一个Intent扩展功能

fun Intent.clearStack() {
    flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}

然后您可以在启动意图之前直接调用此函数

intent.clearStack()

答案 10 :(得分:0)

Intent intent = new Intent(LoginActivity.this,MainActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); startActivity(intent); finish();