因为(您说)首先调用super onCreate是有意义的:考虑一下。
当我要创建时,我的超级创建其资源>创建我的资源。
反之:(有点像栈)
当我想破坏时,我破坏了我的资源>我的超级破坏了他的资源。
从这个意义上讲,它适用于任何两个函数(onCreate / onDestroy,onResume / onPause,onStart / onStop)。自然,onCreate将创建资源,而onDestroy将释放这些资源。顺便说一句,相同的证明适用于其他夫妇。
让我们考虑一下您下载的一个库,该库具有一个LocationActivity,其中包含提供位置的getLocation()函数。最有可能的是,此活动将需要在onCreate()中初始化其内容,这将迫使您首先调用super.onCreate。您已经这样做了,因为您认为这很有道理。现在,在您的onDestroy中,您决定要将该位置保存在SharedPreferences中的某个位置。如果首先调用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);
}
}
最后,如果您的活动称为AnudeepBullaActivity
扩展BaseActivity,然后又想创建SherifElKhatibActivity
一个扩展您的活动怎么办?我应该以什么顺序调用这些super.do
函数?最终是同一回事。
至于你的问题:
我认为Google的意图是告诉我们:无论在哪里,都请致电超级。当然,通常应在一开始就将其命名。Google当然拥有最聪明的工程师和开发人员,因此他们可能在隔离超级调用而不干扰子调用方面做得很好。
我尝试了一下,创建一个由于将何时调用何时调用super而导致崩溃的活动可能并不容易(因为它是Google,我们试图证明是错误的)。
为什么?
这些函数所做的任何事情实际上都是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);
}
mManagedCursors和mManagedDialogs以及mSearchManager都是私有字段。并且任何公共/受保护的api都不会受到此处所做操作的影响。
但是,在API 14中,添加了dispatchActivityDestroyed,以将onActivityDestroyed调度到已注册到您的应用程序的ActivityLifecycleCallbacks。因此,任何依赖于ActivityLifecycleCallbacks中的某些逻辑的代码都会根据调用超级对象的时间而产生不同的结果。例如:
创建一个应用程序类来计算当前正在运行的活动的数量:
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) {}
}
以下内容可能没有意义,也不是一个好的实践,但这只是为了证明一个观点(可能会发现更实际的情况)。创建完成时和最后一个活动时应进入GoodBye活动的MainActivity:
@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活动。
当然,这也不是最佳示例。但是,这表明Google在这里有些混乱。其他任何变量都不会影响您应用程序的行为。但是,将这些分派添加到onDestroy会导致父控件以某种方式干扰您的子类。
我说他们也因为不同的原因而陷入困境。他们(在api 14之前)不仅在超级调用中涉及到final和/或private,而且还调用了不同的内部函数(private),这些内部函数实际上随后分派了onPause ...函数。
例如,performStop
function是被调用的函数,该函数又调用onStop函数:
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;
}
请注意,他们在此函数中的某个位置调用了Activity的onStop。因此,他们可能还把所有代码(包括在super.onStop中)放在对onStop的调用之前或之后,然后仅使用空的onStop超级函数通知有关onStop的子类,甚至不添加SuperNotCalledException或检查此调用。
为此,如果他们在performDestroy中将此分派调用到ActivityLifeCycle,而不是在super.onDestroy的末尾调用它,则无论何时调用超级,我们的活动行为都将是相同的。
无论如何,这是他们要做的第一件事(有点错误),并且仅在API 14中。