因为(你说)首先调用super onCreate是有意义的:想想看。
当我想创建时,我的超级创建其资源>我创建我的资源。
相反:(有点像堆栈)
當我想毀滅時,我摧毀我的資源,>我的超級摧毀他的資源。
从这个意义上说,它适用于任何几个函数(onCreate/onDestroy,onResume/onPause,onStart/onStop)。当然,onCreate 将创建资源,onDestroy 将释放这些资源。顺便说一句,同样的证据也适用于其他夫妇。
让我们考虑一个您下载的库,它具有一个LocationActivity,其中包含提供位置的getLocation()函数。最有可能的是,此活动需要在 onCreate() 中初始化其内容,这将强制您首先调用 super.onCreate。你已经这样做了,因为你觉得这是有道理的。现在,在 onDestroy 中,您决定要将“位置”保存在“共享首选项”中的某个位置。如果先调用 super.onDestroy,则 getLocation 在一定程度上可能会在此调用后返回空值,因为 LocationActivity 的实现会使 onDestroy 中的位置值无效。这个想法是,如果发生这种情况,你不会责怪它。因此,在完成自己的 onDestroy 之后,您会在最后调用 super.onDestroy。我希望这有点道理。
如果上述内容有意义,请考虑在任何时候我们都有遵守上述概念的活动。如果我想扩展这个活动,我可能会有同样的感觉,并遵循相同的顺序,因为相同的参数。
通过归纳,任何活动都应该做同样的事情。对于强制遵循这些规则的活动,下面是一个很好的抽象类:
package mobi.sherif.base;
import android.app.Activity;
import android.os.Bundle;
public abstract class BaseActivity extends Activity {
protected abstract void doCreate(Bundle savedInstanceState);
protected abstract void doDestroy();
protected abstract void doResume();
protected abstract void doPause();
protected abstract void doStart();
protected abstract void doStop();
protected abstract void doSaveInstanceState(Bundle outState);
@Override
protected final void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
doCreate(savedInstanceState);
}
@Override
protected final void onDestroy() {
doDestroy();
super.onDestroy();
}
@Override
protected final void onResume() {
super.onResume();
doResume();
}
@Override
protected final void onPause() {
doPause();
super.onPause();
}
@Override
protected final void onStop() {
doStop();
super.onStop();
}
@Override
protected final void onStart() {
super.onStart();
doStart();
}
@Override
protected final void onSaveInstanceState(Bundle outState) {
doSaveInstanceState(outState);
super.onSaveInstanceState(outState);
}
}
最后,如果你的活动扩展了BaseActivity,后来,我想创建扩展你的活动,该怎么办?我应该以什么顺序调用这些函数?这最终是一回事。AnudeepBullaActivity
SherifElKhatibActivity
super.do
至于你的问题:
我认为谷歌的意图是告诉我们:无论在哪里,请打电话给超级。当然,作为一般做法,请在开始时调用它。谷歌当然拥有最聪明的工程师和开发人员,所以他们可能做得很好,隔离了他们的超级通话,不干扰孩子的通话。
我尝试了一下,可能并不容易(因为它是谷歌,我们试图证明是错误的)创建一个活动,这个活动会因为什么时候超级被调用而崩溃。
为什么?
在这些函数中执行的任何内容实际上对 Activity 类都是私有的,并且永远不会与子类产生任何冲突。例如(在驱逐舰上)
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);
}
mManagedCursors 和 mManagedDialogs 以及 mSearchManager 都是私有字段。任何公共/受保护的 api 都不会受到此处所做操作的影响。
但是,在 API 14 中,添加了 dispatchActivityDestroyed 以调度 onActivityDestroyed 到注册到应用程序的 ActivityLifecycleCallbacks。因此,任何依赖于 ActivityLifecycleCallbacks 中某些逻辑的代码都会根据您调用 super 的时间产生不同的结果。例如:
创建一个计算当前正在运行的活动数的应用程序类:
package mobi.shush;
import android.app.Activity;
import android.app.Application;
import android.app.Application.ActivityLifecycleCallbacks;
import android.os.Bundle;
public class SherifApplication extends Application implements ActivityLifecycleCallbacks {
@Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(this);
}
public int getCount() {
return count;
}
int count = 0;
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
count++;
}
@Override
public void onActivityDestroyed(Activity activity) {
count--;
}
@Override
public void onActivityPaused(Activity activity) {}
@Override
public void onActivityResumed(Activity activity) {}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {}
@Override
public void onActivityStarted(Activity activity) {}
@Override
public void onActivityStopped(Activity activity) {}
}
以下可能没有意义,或者不是一个好的做法,但它只是为了证明一个观点(人们可能会找到一个更真实的情况)。创建 MainActivity,该活动应该在完成时以及最后一个活动时转到 GoodBye 活动:
@Override
protected void onDestroy() {
super.onDestroy();
if(((SherifApplication) getApplication()).getCount() == 0) {
//i want to go to a certain activity when there are no other activities
startActivity(new Intent(this, GoodBye.class));
}
}
如果您在 onDestroy 开始时调用 super.onDestroy,则将启动 GoodBye 活动。如果您在 onDestroy 结束时调用 super.onDestroy,则不会启动 GoodBye 活动。
当然,同样,这不是最佳示例。然而,这表明谷歌在这里搞砸了一点。任何其他变量都不会影响应用的行为。然而,将这些调度添加到 onDestroy 会导致 super 以某种方式干扰你的子类。
我说他们也因为不同的原因搞砸了。他们(在api 14之前)不仅在超级调用中触及最终和/或私有,而且还调用了不同的内部函数(私有),然后真正调度onPause...功能。
例如,function 是调用的函数,它反过来调用 onStop 函数:performStop
final void performStop() {
if (mLoadersStarted) {
mLoadersStarted = false;
if (mLoaderManager != null) {
if (!mChangingConfigurations) {
mLoaderManager.doStop();
} else {
mLoaderManager.doRetain();
}
}
}
if (!mStopped) {
if (mWindow != null) {
mWindow.closeAllPanels();
}
if (mToken != null && mParent == null) {
WindowManagerGlobal.getInstance().setStoppedState(mToken, true);
}
mFragments.dispatchStop();
mCalled = false;
mInstrumentation.callActivityOnStop(this);
if (!mCalled) {
throw new SuperNotCalledException(
"Activity " + mComponent.toShortString() +
" did not call through to super.onStop()");
}
synchronized (mManagedCursors) {
final int N = mManagedCursors.size();
for (int i=0; i<N; i++) {
ManagedCursor mc = mManagedCursors.get(i);
if (!mc.mReleased) {
mc.mCursor.deactivate();
mc.mReleased = true;
}
}
}
mStopped = true;
}
mResumed = false;
}
请注意,他们在此函数中的某个位置调用活动的 onStop。因此,他们可能已经将所有代码(包含在super.onStop中)放在调用onStop之前或之后,然后使用空的onStop超函数通知子类有关onStop的信息,甚至不添加SuperNotCalledException或检查这个调用。
为此,如果他们在performdestroy中将此调度调用到ActiveLifeCycle,而不是在super.onDestroy的末尾调用它,那么无论我们何时调用super,我们的活动的行为都是相同的。
无论如何,这是他们做的第一件事(有点错误),而且只是在API 14中。