因为(你说)首先调用 super onCreate 是有意义的:考虑一下。
当我想创建时,我的超级创建它的资源 > 我创建我的资源。
反过来:(某种堆栈)
当我想破坏时,我破坏了我的资源>我的超级破坏了他的资源。
从这个意义上说,它适用于任何几个函数(onCreate/onDestroy、onResume/onPause、onStart/onStop)。自然,onCreate 将创建资源,而 onDestroy 将释放这些资源。顺便说一句,同样的证据也适用于其他夫妻。
让我们考虑您下载的一个库,它有一个 LocationActivity,其中包含一个提供位置的 getLocation() 函数。最有可能的是,这个活动需要在 onCreate() 中初始化它的东西,这将迫使你首先调用 super.onCreate。你已经这样做了,因为你觉得这很有意义。现在,在您的 onDestroy 中,您决定要将 Location 保存在 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
函数?最终是一样的。
至于你的问题:
我认为谷歌的意图是告诉我们:无论在哪里,请致电超级。当然,作为一般做法,在开始时调用它。谷歌当然拥有最聪明的工程师和开发人员,所以他们可能在隔离超级呼叫而不干扰子呼叫方面做得很好。
我尝试了一点,可能不容易(因为我们试图证明是谷歌是错误的)创建一个由于何时调用 super 而容易崩溃的活动。
为什么?
在这些函数中所做的任何事情都是 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 中某些逻辑的代码都将根据您调用 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 会导致超级以某种方式干扰您的子类。
我说他们也因为不同的原因搞砸了。他们不仅(在 api 14 之前)仅在超级调用中涉及最终和/或私有的内容,而且他们还调用了不同的内部函数(私有),然后真正调度了 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。因此,他们也可以在调用 onStop 之前或之后放置所有代码(包含在 super.onStop 中),然后使用空的 onStop 超级函数通知子类关于 onStop,甚至无需添加 SuperNotCalledException 或检查此调用。
为此,如果他们在 performDestroy 中将此调度调用到 ActivityLifeCycle 而不是在 super.onDestroy 的末尾调用它,那么无论我们何时调用 super ,我们的 Activity 的行为都会是相同的。
无论如何,这是他们做的第一件事(有点错误),而且只在 API 14 中。