【问题标题】:What is the default implementation of onBackPressed() in ActivityActivity中onBackPressed()的默认实现是什么
【发布时间】:2016-04-29 05:48:43
【问题描述】:

我想知道onBackPressed()Activity中的默认实现。 onBackPressed()的默认实现中的Activityrecover如何处理?

以下是我遇到的问题。我有一个测试Activity 这样的代码:

public class MainActivity extends Activity {
    public static boolean test = false;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    protected void onResume() {
        super.onResume();
        Toast.makeText(this,"is "+test,Toast.LENGTH_LONG).show();
        test = !test;
    }
}

当我第一次进入应用程序时,我得到“是假的”。然后我单击返回按钮并进入主屏幕。之后,当我进入应用程序时,我得到了 Toast '是真的'。我认为onBackPressed() 在返回主屏幕时应该会杀死我的应用程序,但事实并非如此。这是我的问题。

如果我像这样覆盖onBackPressed()

@Override
public void onBackPressed() {
//  super.onBackPressed();
    finish();
    try {
        android.os.Process.killProcess(android.os.Process.myPid());
    } catch (Exception e) {
        e.printStackTrace();
    }
}

进入应用后,我总是得到 Toast 'is false'。

谁能解释这个问题并告诉我onBackPressed() 的默认实现是什么?

想详细了解onBackPressed()的流程。看了onBackPressed()上的部分源码,但是看不懂。

提前致谢。

【问题讨论】:

  • 似乎一切正常。你破坏了你的进程和false字段“清除”。那么有什么问题呢?
  • 没有。我只是单击后按菜单按钮。返回主屏幕后,我再次进入此应用程序,但测试为真。这意味着,默认的 onBackPressed 并没有破坏我的进程。
  • 默认onBackPressed 不会破坏您的进程。它会破坏您的 activity 和所有与活动相关的对象(片段、ui)。
  • @Foxinsocks 破坏我的活动而不回收 MainActivity.class ?
  • not recycle 是什么意思? ClassLoader 你的活动不会卸载 class,如果你是这个意思。

标签: android android-activity android-lifecycle kill-process onbackpressed


【解决方案1】:

ActivityonBackPressed() 的默认实现可能不会告诉你很多关于实际Activity/应用程序生命周期的信息。您应该深入了解Android(和Linux)关于应用程序/进程终止的内部“机制”。

应用程序开发人员应该知道的是,一旦Activity 在后台(按下主页按钮,收到来电等,即onPause() 后跟onStop() 已被调用),它的进程可能(类似于你对android.os.Process.killProcess(...)) 做了,否则可能不会被杀死。请参阅 Dianne Hackborn 的 Multitasking the Android Way 以获取参考。

至于通过按下返回按钮完成Activity,并不意味着它的实例会立即被杀死并收集内存垃圾(参见this answer)。这只是意味着您下次导航回 Activity 的新实例时会创建它。

关于你的代码和声明

当我第一次进入应用程序时,我得到“是假的”。然后我单击返回按钮并进入主屏幕。之后,当我进入应用程序时,我得到了 Toast '是真的'。我认为 onBackPressed() 返回主屏幕时应该杀死我的应用程序,但它没有。

Activity 在后台时系统没有终止进程就是这种情况(同样,不能保证)。如果是这样,Toast 将显示false

为了检查每次按下后退按钮然后导航回应用程序时是否创建了一个新的MainActivity 实例,我不建议使用静态变量 - 似乎不是这样显而易见(例如,请参阅 is it possible for Android VM to garbage collect static variables...Are static fields open for garbage collection?)。

除了您只是在truefalse 之间切换,这可能会造成混淆。例如,您可以使用非静态变量来增加它,而不是使用静态变量,或者烘烤当前Activity 实例的哈希码,例如Toast.makeText(this,"is " + this.hashCode(), Toast.LENGTH_LONG).show()。通过这样做,Activity 生命周期应该按照 documentation 行事。

如果我覆盖 onBackPressed() ... 在我进入应用程序后,我总是得到 Toast 'is false'。

这或多或少类似于系统杀死您的应用程序的进程。

【讨论】:

  • 谢谢。顺便说一句,onBackPressed 是否调用 onDestory
  • 不是直接的。调用onBackPressed() 会隐式导致系统调用onDestroy()
  • 隐含的意思是什么?我试过onBackPressed。应用直接返回主屏幕,不登录Destroy。
  • 系统在内存不足时可能不会调用onDestroy(),但通常会调用它。我猜你忘了删除Process.killProcess(),它会在不等待任何回调的情况下残酷地终止进程......“隐含”意味着“所有的魔法”都没有发生在方法中,它从那里开始。 Activity 只是一个应用程序组件,基本上是一个Java 对象。如果您想知道在 Java 应用程序组件下面发生了什么,我建议您观察源代码并阅读 this book
  • 哦,是的,我忘了删除Process.killProcess()
【解决方案2】:

从 AOSP Activity 类中找到 here

/**
 * Called when the activity has detected the user's press of the back
 * key.  The default implementation simply finishes the current activity,
 * but you can override this to do whatever you want.
 */
public void onBackPressed() {
    if (mActionBar != null && mActionBar.collapseActionView()) {
        return;
    }

    if (!mFragments.getFragmentManager().popBackStackImmediate()) {
        finishAfterTransition();
    }
}

所以基本上当你调用完成时,进程实际上并没有被破坏。您可以阅读更多关于 here 的信息。这意味着您的应用程序中的内存不会被破坏,因此当您重新启动应用程序时,会记住之前的 boolean 值。

在您重写实现的情况下,您正在显式销毁进程,这将清除您的活动状态的内存,因此当您重新启动应用程序时,boolean 初始化将再次发生。

【讨论】:

  • 你能详细描述一下onBackPressed的所有过程吗?谢谢。事实上,我已经阅读了 popBackStackImmediate() source 。我只是无法描述 android 在 onBackPressed 中所做的所有事情。
  • 考虑这个简单的例子:你正在使用你的安卓手机并且在主屏幕上。当时只有 1 个片段打开(主屏幕)。这意味着片段堆栈上没有片段。现在,考虑打开浏览器。浏览器打开,现在打开了一个新片段。主屏幕片段现在被放置在堆栈上,因此堆栈上有 1 个项目。现在考虑再次使用后退按钮。 Android 将检查堆栈中是否有片段。既然有1,就会关闭当前的fragment,恢复栈上的fragment。我希望这会有所帮助。
猜你喜欢
  • 1970-01-01
  • 2015-04-14
  • 1970-01-01
  • 2019-02-01
  • 1970-01-01
  • 2015-09-22
  • 2014-07-02
  • 1970-01-01
相关资源
最近更新 更多