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?
在我看来:不是一件事。
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()");
}
mCalled在Activity.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);
}
在这里,排序可能是重要的,这取决于你的活动是如何设置的,以及调用super.onDestroy()是否会干扰后面的代码。
最后,语句总是调用超类方法似乎没有足够的证据来支持它。更糟糕的是(对于语句),下面的代码是从android.app.ListActivity:
public class ListActivity extends Activity {
....
@Override
protected void onDestroy() {
mHandler.removeCallbacks(mRequestFocus);
super.onDestroy();
}
....
}
并且,从LunarLander示例应用程序包括在android sdk:
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()的调用。在super.onPause()之后使用setResult(…)设置结果将不起作用。他后来在对他的回答的评论中澄清了这一点。
用户Sherif elKhatib:解释为什么让超类初始化它的资源,并且销毁它的资源最后从逻辑:
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()调用的位置影响程序逻辑的场景。
从马克的答案:
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类的方法时不起作用。他还声称,首先调用超类方法被认为是最佳实践。但是,我不能证实这一点。
用户LOG_TAG:解释为什么调用superclass构造函数需要在其他任何事情之前。在我看来,这个解释不会增加被问的问题。
结束注意:信任,但验证。此页面上的大多数答案都遵循此方法,以查看语句始终调用超类方法是否首先具有逻辑支持。事实证明,它不是;至少,不是在类Activity的情况下。通常,应该通过超类的源代码来确定是否需要对super的方法进行排序调用。