由于(你说)先调用超类onCreate有意义:请思考一下。
当我想创建时,我的超类会创建它的资源 > 我创建我的资源。
反过来的情况:(一种堆栈)
当我想要销毁时,我会销毁我的资源 > 我的超类会销毁它的资源。
在这个意义上,它适用于任何一对函数(onCreate/onDestroy、onResume/onPause、onStart/onStop)。自然地,onCreate将创建资源并且onDestroy将释放这些资源。顺便说一下,相同的证明也适用于其他一对函数。
让我们考虑你下载了一个库,其中包含一个LocationActivity,该活动包含一个getLocation()函数,用于提供位置信息。很可能,这个活动需要在onCreate()中初始化其内容,这将迫使你先调用super.onCreate。你已经这样做是因为你觉得这是有意义的。现在,在你的onDestroy中,你决定要在SharedPreferences中保存位置。如果你首先调用super.onDestroy,则在此调用之后,getLocation可能会返回null值,因为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的意图是告诉我们:无论何时都请调用super。作为一般惯例,当然要在开头调用它。 Google当然拥有最聪明的工程师和开发人员,所以他们可能已经很好地隔离了他们的超级调用并且不会干扰子类调用。
我尝试了一下,可能不容易(因为我们正在试图证明谷歌是错误的)创建一个由于调用super的时间不同而崩溃的活动。
为什么?
在这些函数中执行的任何操作都是Activity类的私有内容,并且永远不会与您的子类产生冲突。例如(onDestroy)
protected void onDestroy() {
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onDestroy " + this);
mCalled = true;
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;
}
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();
}
if (mSearchManager != null) {
mSearchManager.stopSearch();
}
getApplication().dispatchActivityDestroyed(this);
}
mManagedCursors、mManagedDialogs和mSearchManager都是私有字段。并且这里所做的任何操作都不会影响公共/受保护的API。
然而,在API 14中,dispatchActivityDestroyed被添加到dispatchActivityDestroyed上,以向注册到您的应用程序的ActivityLifecycleCallbacks分派onActivityDestroyed。因此,任何依赖于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) {}
}
以下内容可能有些不太合理,但只是为了证明一个观点(更真实的场景可能会出现),创建MainActivity,当它完成时,它应该转到GoodBye活动,并且当它是最后一个活动时:
@Override
protected void onDestroy() {
super.onDestroy();
if(((SherifApplication) getApplication()).getCount() == 0) {
startActivity(new Intent(this, GoodBye.class));
}
}
如果你在onDestroy的开头调用super.onDestroy,那么GoodBye活动将被启动。如果你在onDestroy的结尾调用super.onDestroy,则不会启动GoodBye活动。
当然,再次说明,这不是最佳示例。但是这表明Google在这里有点搞砸了。其他任何变量都不会影响应用程序的行为。但是,在onDestroy中添加这些分派会使超类以某种方式干扰您的子类。
我还因不同的原因说他们弄糟了。在api 14之前,他们(只触及final和/或private)也调用了不同的内部函数(私有),这些函数真正地调度了onPause ...函数。
例如,performStop函数是所调用的函数,这个函数进而调用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 super函数通知子类关于onStop的情况,甚至不需要添加SuperNotCalledException或者检查是否有调用发生。
为了实现这一点,如果他们在performDestroy中调用了ActivityLifeCycle的dispatch,而不是在super.onDestroy结束时调用,那么我们的activity行为将不受调用super的时间影响。
总之,这是他们做的第一件事(有点错误),而且仅适用于API 14。