Android - 如何覆盖"后退"按钮,以便它不完成()我的活动?

Don*_*rty 193 android back-button nullpointerexception onkeypress android-activity

我目前有一个活动,当它显示时,通知也将显示在通知栏中.

这样,当用户按下主页并将活动推送到后台时,他们可以通过通知返回活动.

当用户按下后退按钮时,问题就出现了,我的活动被破坏但是通知仍然存在,因为我希望用户能够按下但仍然能够通过通知进入活动.但是当用户尝试这个时,我会尝试Null Pointers尝试启动一项新活动,而不是重新启动旧活动.

所以基本上我希望Back按钮的行为与Home按钮完全相同,这是我到目前为止的尝试方式:


        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event)  {
            if (Integer.parseInt(android.os.Build.VERSION.SDK) < 5
                    && keyCode == KeyEvent.KEYCODE_BACK
                    && event.getRepeatCount() == 0) {
                Log.d("CDA", "onKeyDown Called");
                onBackPressed();
            }

            return super.onKeyDown(keyCode, event);
        }

        public void onBackPressed() {
            Log.d("CDA", "onBackPressed Called");
            Intent setIntent = new Intent(Intent.ACTION_MAIN);
            setIntent.addCategory(Intent.CATEGORY_HOME);
            setIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(setIntent); 

            return;
        }   
Run Code Online (Sandbox Code Playgroud)

但是上面的代码似乎仍然允许我的Activity被销毁,如何在按下后退按钮时阻止我的Activity被销毁?

eka*_*was 262

删除您的密钥监听器或true在您拥有时返回KEY_BACK.

你只需要以下赶返回键(确保不叫onBackPressed()).

此外,如果您计划在后台运行服务,请务必查看startForeground()并确保持续通知,否则如果需要释放内存,Android将终止您的服务.

@Override
public void onBackPressed() {
   Log.d("CDA", "onBackPressed Called");
   Intent setIntent = new Intent(Intent.ACTION_MAIN);
   setIntent.addCategory(Intent.CATEGORY_HOME);
   setIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   startActivity(setIntent);
}
Run Code Online (Sandbox Code Playgroud)


Teo*_*nke 68

只用一行代码就可以更容易地实现它:

@Override
public void onBackPressed() {
   moveTaskToBack(true);
}
Run Code Online (Sandbox Code Playgroud)

  • 这应该是公认的答案。这正是问题所要求的,并且正在使用干净的内置功能。 (3认同)

kis*_*swa 12

我认为你想要的不是覆盖后退按钮(这似乎不是一个好主意 - Android操作系统定义了这种行为,为什么要更改它?),但要使用活动生命周期并将设置/数据保留在onSaveInstanceState(Bundle)事件.

@Override
onSaveInstanceState(Bundle frozenState) {
    frozenState.putSerializable("object_key",
        someSerializableClassYouWantToPersist);
    // etc. until you have everything important stored in the bundle
}
Run Code Online (Sandbox Code Playgroud)

然后使用onCreate(Bundle)从该持久化bundle中获取所有内容并重新创建状态.

@Override
onCreate(Bundle savedInstanceState) {
    if(savedInstanceState!=null){ //It could be null if starting the app.
        mCustomObject = savedInstanceState.getSerializable("object_key");
    }
    // etc. until you have reloaded everything you stored
}
Run Code Online (Sandbox Code Playgroud)

考虑上面的伪代码,指出你正确的方向.阅读活动生命周期应该可以帮助您确定实现所需内容的最佳方式.

  • 我至少遇到过几种情况,我想在不实际启动新活动的情况下模拟标准的活动堆栈行为.在这些情况下,我认为,覆盖默认的onBackPressed()行为是合适的.但总的来说,我同意:避免重写. (5认同)
  • 我同意@Matt.我目前正在开发一款使用NDK的跨平台游戏.因此,如果一切都是单一活动,这是最简单的.因此,后退按钮的默认行为是逃避应用程序,这不是大多数用户所期望的.因此,我不得不覆盖默认行为,以使活动的行为不同,就像用户实际上进行了不同的活动一样,并且只在某些情况下退出应用程序. (4认同)

and*_*-BD 11

干脆做这个..

@Override
public void onBackPressed() {
    //super.onBackPressed();
}
Run Code Online (Sandbox Code Playgroud)

注释掉//super.onBackPressed(); 会做的


小智 6

尝试这个:

@Override
public void onBackPressed() {
    finish();
}
Run Code Online (Sandbox Code Playgroud)