gpt4 book ai didi

java - 在 onPause、onStop 和 onDestroy 方法中调用父类(super class)方法的正确顺序是什么?为什么?

转载 作者:IT老高 更新时间:2023-10-28 11:43:56 25 4
gpt4 key购买 nike

我刚刚浏览了Android Developer Site,刷新了Activity生命周期,在每个代码示例中,父类(super class)方法旁边都有一条注释,上面写着“始终首先调用父类(super class)方法”。

虽然这在创建半周期:onCreate、onStart 和 onResume 中是有意义的,但我对销毁半周期的正确过程有点困惑:onPause、onStop、onDestroy。

在销毁特定于实例的资源可能依赖的父类(super class)资源之前,首先销毁实例特定的资源是有意义的,而不是相反。但评论表明并非如此。我错过了什么?

编辑:由于人们似乎对问题的 Intent 感到困惑,我想知道以下哪项是正确的? 为什么?

1.Google 建议

    @Override
protected void onStop() {
super.onStop(); // Always call the superclass method first

//my implementation here
}

2.另一种方式

    @Override
protected void onStop() {
//my implementation here

super.onStop();
}

最佳答案

Destroying the instance specific resources first, before destroying superclass resources that the instance specific resources may depend upon makes sense, not the other way round. But the comments suggest otherwise. What am I missing?

在我看来:不是一件事。

Mark(又名 CommonsWare on SO)的这个回答阐明了这个问题:Link - Should the call to the superclass method be the first statement? .但是,您可以在他的回答中看到以下评论:

But why official doc says: "Always call the superclass method first" in onPause()?

回到第一格。好吧,让我们从另一个角度来看这个。我们知道 Java 语言规范没有指定必须放置对 super.overridenMethod() 的调用的顺序(或者是否必须放置调用)。

在类 Activity 的情况下,super.overridenMethod() 调用是必需的并且强制:

if (!mCalled) {
throw new SuperNotCalledException(
"Activity " + mComponent.toShortString() +
" did not call through to super.onStop()");
}

mCalledActivity.onStop() 中设置为 true。

现在,唯一需要讨论的细节是排序。

我也知道两者都有效

当然。查看Activity.onPause()的方法体:

protected void onPause() {
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onPause " + this);

// This is to invoke
// Application.ActivityLifecyleCallbacks.onActivityPaused(Activity)
getApplication().dispatchActivityPaused(this);

// The flag to enforce calling of this method
mCalled = true;
}

无论您采用哪种方式调用 super.onPause(),都可以。 Activity.onStop() 有一个类似的方法体。但是看看Activity.onDestroy():

protected void onDestroy() {
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onDestroy " + this);
mCalled = true;

// dismiss any dialogs we are managing.
if (mManagedDialogs != null) {
final int numDialogs = mManagedDialogs.size();
for (int i = 0; i < numDialogs; i++) {
final ManagedDialog md = mManagedDialogs.valueAt(i);
if (md.mDialog.isShowing()) {
md.mDialog.dismiss();
}
}
mManagedDialogs = null;
}

// close any cursors we are managing.
synchronized (mManagedCursors) {
int numCursors = mManagedCursors.size();
for (int i = 0; i < numCursors; i++) {
ManagedCursor c = mManagedCursors.get(i);
if (c != null) {
c.mCursor.close();
}
}
mManagedCursors.clear();
}

// Close any open search dialog
if (mSearchManager != null) {
mSearchManager.stopSearch();
}

getApplication().dispatchActivityDestroyed(this);
}

在这里,排序可能可能很重要,具体取决于您的 Activity 设置方式,以及调用 super.onDestroy() 是否会干扰后面的代码。

最后一句话,始终首先调用父类(super class)方法这句话似乎没有太多证据支持它。更糟糕的是(对于语句)以下代码取自 android.app.ListActivity:

public class ListActivity extends Activity {

....

@Override
protected void onDestroy() {
mHandler.removeCallbacks(mRequestFocus);
super.onDestroy();
}
....
}

并且,来自 android sdk 中包含的 LunarLander 示例应用程序:

public class LunarLander extends Activity {

....

@Override
protected void onPause() {
mLunarView.getThread().pause(); // pause game when Activity pauses
super.onPause();
}
....
}

总结和值得一提:

用户 Philip Sheard :提供一个场景,如果使用 startActivityForResult(Intent) 启动 Activity,则必须延迟对 super.onPause() 的调用。使用 setResult(...) after super.onPause() 设置结果将不起作用。他后来在对他的回答的评论中澄清了这一点。

User Sherif elKhatib:解释为什么让父类(super class)首先初始化其资源并最后销毁其资源的逻辑:

Let us consider a library you downloaded which has a LocationActivity that contains a getLocation() function that provides the location. Most probably, this activity will need to initialize its stuff in the onCreate() which will force you to call the super.onCreate first. You already do that because you feel it makes sense. Now, in your onDestroy, you decide you want to save the Location somewhere in the SharedPreferences. If you call super.onDestroy first, it is to a certain extent possible that getLocation will return a null value after this call because the implementation of LocationActivity nullifies the location value in the onDestroy. The idea is that you wouldn't blame it if this happens. Therefore, you would call super.onDestroy at the end after you're done with your own onDestroy.

他继续指出:如果子类与父类适当隔离(在资源依赖方面),则 super.X() 调用不需要遵守任何顺序规范.

请参阅他在此页面上的回答,以通读 super.onDestroy() 调用 确实 影响程序逻辑的场景。

来自 Mark 的回答:

Methods you override that are part of component creation (onCreate(), onStart(), onResume(), etc.), you should chain to the superclass as the first statement, to ensure that Android has its chance to do its work before you attempt to do something that relies upon that work having been done.

Methods you override that are part of component destruction (onPause(), onStop(), onDestroy(), etc.), you should do your work first and chain to the superclass as the last thing. That way, in case Android cleans up something that your work depends upon, you will have done your work first.

Methods that return something other than void (onCreateOptionsMenu(), etc.), sometimes you chain to the superclass in the return statement, assuming that you are not specifically doing something that needs to force a particular return value.

Everything else -- such as onActivityResult() -- is up to you, on the whole. I tend to chain to the superclass as the first thing, but unless you are running into problems, chaining later should be fine.

Bob Kerns 来自 this thread :

It's a good pattern [(the pattern that Mark suggests above)], but I've found some exceptions. For example, the theme I wanted to apply to my PreferenceActivity wouldn't take effect unless I put it before the superclass's onCreate().

用户 Steve Benett 也注意到了这一点:

I only know one situation, where the timing of the super call is necessary. If you wanna alter the standard behavior of the theme or the display and such in onCreate, you have to do it before you call super to see an effect. Otherwise AFAIK there is no difference at which time you call it.

用户 Sunil Mishra 确认在调用 Activity 类的方法时顺序(很可能)不起作用。他还声称首先调用父类(super class)方法被认为是最佳实践。但是,我无法证实这一点。

User LOG_TAG :解释为什么调用父类(super class)构造函数 需要在所有其他事情之前。在我看来,这种解释并没有增加所提出的问题。

尾注:信任,验证。此页面上的大多数答案都遵循这种方法,以查看语句 始终首先调用父类(super class)方法 是否具有逻辑支持。事实证明,它没有;至少,在类 Activity 的情况下不是这样。通常,应该通读父类(super class)的源代码以确定是否需要对父类(super class)方法的排序调用。

关于java - 在 onPause、onStop 和 onDestroy 方法中调用父类(super class)方法的正确顺序是什么?为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18821481/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com