最近我在许多Android应用和游戏中注意到这种模式:当点击后退按钮“退出”应用时,Toast会出现类似于“请再次点击后退退出”的消息。

我在想,当我越来越频繁地看到它时,这是一个内置的功能,你可以在某个活动中访问它吗?我已经看了很多类的源代码,但我似乎找不到任何关于这一点。

当然,我可以想到一些很容易实现相同功能的方法(最简单的可能是在活动中保留一个布尔值,指示用户是否已经单击过一次…),但我想知道这里是否已经有一些东西。

编辑:正如@LAS_VEGAS所提到的,我并不是指传统意义上的“退出”。(即终止)我的意思是“回到应用程序启动活动启动之前打开的任何东西”,如果这有意义的话:)


当前回答

我认为这个方法比Zefnus好一点。只调用一次System.currentTimeMillis()并忽略return;:

long previousTime;

@Override
public void onBackPressed()
{
    if (2000 + previousTime > (previousTime = System.currentTimeMillis())) 
    { 
        super.onBackPressed();
    } else {
        Toast.makeText(getBaseContext(), "Tap back button in order to exit", Toast.LENGTH_SHORT).show();
    }
}

其他回答

Sudheesh B Nair对这个问题有一个很好的(被接受的)答案,我认为应该有一个更好的选择,比如;

测量所经过的时间并检查自上次回按以来TIME_INTERVAL毫秒(例如2000)是否经过了什么错误?下面的示例代码使用System.currentTimeMillis();onBackPressed()被调用来存储时间;

private static final int TIME_INTERVAL = 2000; // # milliseconds, desired time passed between two back presses.
private long mBackPressed;

@Override
public void onBackPressed()
{
    if (mBackPressed + TIME_INTERVAL > System.currentTimeMillis()) 
    { 
        super.onBackPressed(); 
        return;
    }
    else { Toast.makeText(getBaseContext(), "Tap back button in order to exit", Toast.LENGTH_SHORT).show(); }

    mBackPressed = System.currentTimeMillis();
}

回到公认的答案批评;使用一个标志来指示它是否在最后的TIME_INTERVAL(比如2000)毫秒内被按下,而set - reset是通过Handler的postDelayed()方法来执行的,这是我想到的第一件事。但是postDelayed()操作应该在活动关闭时取消,删除Runnable。

为了移除Runnable,它不能被声明为匿名,并且必须与Handler一起声明为成员。然后可以适当地调用Handler的removeCallbacks()方法。

下面的示例是演示;

private boolean doubleBackToExitPressedOnce;
private Handler mHandler = new Handler();

private final Runnable mRunnable = new Runnable() {
    @Override
    public void run() {
        doubleBackToExitPressedOnce = false;                       
    }
};

@Override 
protected void onDestroy() 
{ 
    super.onDestroy();

    if (mHandler != null) { mHandler.removeCallbacks(mRunnable); }
}

@Override
public void onBackPressed() {
    if (doubleBackToExitPressedOnce) {
        super.onBackPressed();
        return;
    }

    this.doubleBackToExitPressedOnce = true;
    Toast.makeText(this, "Please click BACK again to exit", Toast.LENGTH_SHORT).show();

    mHandler.postDelayed(mRunnable, 2000);
}

感谢@NSouth的贡献;为了防止在应用程序关闭后出现toast消息,toast可以被声明为成员,比如mExitToast,并且可以通过mExitToast.cancel()取消;就在super.onBackPressed()之前;调用。

这是被接受和投票最多的回应,但这个片段用了Snackbar而不是Toast。

boolean doubleBackToExitPressedOnce = false;

    @Override
    public void onBackPressed() {
        if (doubleBackToExitPressedOnce) {
            super.onBackPressed();
            return;
        }

        this.doubleBackToExitPressedOnce = true;
        Snackbar.make(content, "Please click BACK again to exit", Snackbar.LENGTH_SHORT)
                .setAction("Action", null).show();


        new Handler().postDelayed(new Runnable() {

            @Override
            public void run() {
                doubleBackToExitPressedOnce=false;
            }
        }, 2000);
    }

它不是内置的功能。我认为这甚至不是被推荐的行为。Android应用程序并不意味着退出:

为什么Android应用程序不提供“退出”选项?

我用这个

import android.app.Activity;
import android.support.annotation.StringRes;
import android.widget.Toast;

public class ExitApp {

    private static long lastClickTime;

    public static void now(Activity ctx, @StringRes int message) {
        now(ctx, ctx.getString(message), 2500);
    }

    public static void now(Activity ctx, @StringRes int message, long time) {
        now(ctx, ctx.getString(message), time);
    }

    public static void now(Activity ctx, String message, long time) {
        if (ctx != null && !message.isEmpty() && time != 0) {
            if (lastClickTime + time > System.currentTimeMillis()) {
                ctx.finish();
            } else {
                Toast.makeText(ctx, message, Toast.LENGTH_SHORT).show();
                lastClickTime = System.currentTimeMillis();
            }
        }
    }

}

使用到事件onBackPressed

@Override
public void onBackPressed() {
   ExitApp.now(this,"Press again for close");
}

或ExitApp.now(这个,R.string.double_back_pressed)

对于需要关闭的更改秒,指定毫秒

ExitApp.now (R.string.double_back_pressed, 5000)

在这种情况下,Snackbar是比Toast更好的选择来显示退出动作。下面是小吃店的工作方法。

@Override
        public void onBackPressed() {
            if (doubleBackToExitPressedOnce) {
                super.onBackPressed();
                return;
            }
            this.doubleBackToExitPressedOnce = true;
            Snackbar.make(this.getWindow().getDecorView().findViewById(android.R.id.content), "Please click BACK again to exit", Snackbar.LENGTH_SHORT).show();

            new Handler().postDelayed(new Runnable() {

                @Override
                public void run() {
                    doubleBackToExitPressedOnce=false;
                }
            }, 2000);
        }