ChatGPT解决这个技术问题 Extra ChatGPT

覆盖后退按钮以充当主页按钮

在按下后退按钮时,我希望我的应用程序进入停止状态,而不是破坏状态。

在 Android docs 中,它指出:

...并非所有活动都有在按下 BACK 时被销毁的行为。当用户在 Music 应用程序中开始播放音乐然后按下 BACK 时,应用程序会覆盖正常的返回行为,防止播放器 Activity 被破坏,并继续播放音乐,即使它的 Activity 不再可见

如何在我自己的应用程序中复制此功能?

我觉得应该有三种可能...

捕获后退按钮按下(如下所示),然后调用主页按钮调用的任何方法。 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if ((keyCode == KeyEvent.KEYCODE_BACK)) { Log.d(this.getClass().getName(), "后退按钮被按下"); } 返回 super.onKeyDown(keyCode, event);捕获后退按钮按下,然后欺骗主页按钮按下。捕获后退按钮按下,然后启动主屏幕的 Activity,有效地将我的应用程序的 Activity 置于停止状态。

编辑:我了解服务,并且正在与此问题相关的应用程序中使用服务。这个问题专门关于将 Activity 置于停止状态而不是按下后退按钮时的销毁状态。


U
Uxonith

大多数情况下,您需要创建一个 Service 来在后台执行某些操作,而可见的 Activity 只是控制这个 Service。 (我确信音乐播放器的工作方式相同,因此文档中的示例似乎有点误导。)如果是这种情况,那么您的 Activity 可以像往常一样 finishService 仍然是跑步。

一种更简单的方法是捕获 Back 按钮按下并调用 moveTaskToBack(true),如下所示:

// 2.0 and above
@Override
public void onBackPressed() {
    moveTaskToBack(true);
}

// Before 2.0
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        moveTaskToBack(true);
        return true;
    }
    return super.onKeyDown(keyCode, event);
}

我认为首选选项应该是 Activity 正常完成并能够重新创建自身,例如如果需要从 Service 读取当前状态。但有时可以将 moveTaskToBack 用作快速替代方案。

注意:正如 Dave 所指出的,Android 2.0 下面引入了一个新的 onBackPressed 方法,以及 these recommendations 如何处理后退按钮。


moveTaskToBack() 似乎可以按需要工作。使用这种方法可能有什么缺点?是否有可能无法按预期工作的情况?
在更仔细地阅读了它的文档之后,我实际上认为它应该可以正常工作。 (我最初认为它适用于活动,但实际上它说的是“包含此活动的任务”。)但是您当然应该自己测试它。 :)
感谢 Mirko,该方法似乎效果很好。如果您在答案底部更突出您的编辑以供稍后查看此问题的人使用,那可能会很酷 - 因为那是我一直在寻找的!
请阅读 android-developers.blogspot.com/2009/12/… 了解处理后退键的推荐方式。
@bdls 理论上,如果系统资源不足,您的后台活动可能会被系统杀死,因此为了安全起见,无论如何它应该能够重新创建自己。我查看了 Android Music 应用程序的源代码,没有看到任何特殊的后退按钮处理。
Z
Zitrax

使用以下代码:

public void onBackPressed() {    
    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_MAIN);
    intent.addCategory(Intent.CATEGORY_HOME);
    startActivity(intent);
}

D
Dave Webb

如果您想捕捉返回按钮,请查看 this post on the Android Developer Blog。它涵盖了在 Android 2.0 中执行此操作的更简单方法以及在 1.x 和 2.0 上运行的应用程序执行此操作的最佳方法。

但是,如果您的 Activity 已停止,它仍然可能会被终止,具体取决于设备上的内存可用性。如果您希望进程在没有 UI 的情况下运行,您应该创建一个 ServiceThe documentation says the following about Services:

服务没有可视化的用户界面,而是在后台无限期地运行。例如,服务可能会在用户处理其他事务时播放背景音乐,或者它可能会通过网络获取数据或计算某些内容并将结果提供给需要它的活动。

这些似乎适合您的要求。


L
Lucifer

尝试覆盖 android.app.Activity 类中定义的 void onBackPressed()


由于 android 2.0 这是正确的覆盖。 developer.android.com/sdk/android-2.0.html
c
craigk

如果它对其他人有帮助,我有一个带有 2 个布局的活动,我为了可见性而打开和关闭,试图模拟一种 page1 > page2 结构。如果他们在第 2 页并按下后退按钮,我希望他们返回到第 1 页,如果他们在第 1 页上按下后退按钮,它应该仍然可以正常工作。它非常基本,但它有效

@Override
public void onBackPressed() {
// check if page 2 is open
    RelativeLayout page2layout = (RelativeLayout)findViewById(R.id.page2layout);
    if(page2layout.getVisibility() == View.VISIBLE){
        togglePageLayout(); // my method to toggle the views
        return;
    }else{
        super.onBackPressed(); // allows standard use of backbutton for page 1
    }

}

希望它可以帮助某人,干杯


Z
Zar E Ahmer

工作示例..

确保不要调用 super.onBackPressed();

@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);
}

这样,您的 Back Button 就像 Home button 一样。它不会完成您的活动,而是将其带到后台

第二种方法是在 onBackPressed 中调用 moveTaskToBack(true); 并确保删除 super.onBackPressed


u
user1524315

更好的是,OnPause() 怎么样:

当活动进入后台但尚未(尚未)被杀死时,作为活动生命周期的一部分调用。 onResume() 的对应项。

当活动 B 在活动 A 之前启动时,将在 A 上调用此回调。在 A 的 onPause() 返回之前不会创建 B,因此请务必enter code here不要在这里做任何冗长的事情。

此回调主要用于保存活动正在编辑的任何持久状态,并确保如果没有足够的资源来启动新活动而没有首先杀死该活动,则不会丢失任何内容。

这也是一个很好的地方来做一些事情,比如停止动画和其他消耗大量 CPU 的事情,以便尽快切换到下一个活动,或者关闭诸如相机之类的独占访问资源。


S
SaiLiu

在 android 2.0 之后覆盖 onBackPressed()。如

@Override
public void onBackPressed() {
    moveTaskToBack(true);
}

S
Sameer Z.

我已经使用@Mirko N. answser 使用了新的自定义 EditText

 public class EditViewCustom extends EditText {

    Button cancelBtn;
    RelativeLayout titleReleLayout;
    public EditViewCustom(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public EditViewCustom(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public EditViewCustom(Context context) {
        super(context);
    }

    public void setViews(Button cancelBtn,RelativeLayout titleReleLayout){
        this.cancelBtn = cancelBtn;
        this.titleReleLayout = titleReleLayout;
    }

    @Override
    public boolean onKeyPreIme(int keyCode, KeyEvent event) {
        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
            Log.d("KEYCODE_BACK","KEYCODE_BACK");
            cancelBtn.setVisibility(View.GONE);
            this.setFocusableInTouchMode(false);
            this.setFocusable(false);
            titleReleLayout.setVisibility(View.VISIBLE);

            return super.onKeyPreIme(keyCode, event);
          }

        return super.onKeyPreIme(keyCode, event);
    }

}

然后从您的活动中设置数据

 searchEditView.setViews(cancelBtn, titleRelativeLayout);

谢谢你。


u
ubulon

我已经尝试了上述所有解决方案,但没有一个对我有用。当我尝试以调用 onCreate 的方式返回 MainActivity 时,以下代码帮助了我:

Intent.FLAG_ACTIVITY_CLEAR_TOP 是关键。

  @Override
  public void onBackPressed() {
      Intent intent = new Intent(this, MainActivity.class);
      intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
      startActivity(intent);
  }