Поскольку (вы говорите), имеет смысл сначала вызвать super onCreate: подумайте об этом.
Когда я хочу творить, Мой супер создает свои ресурсы> Я создаю свои ресурсы.
Наоборот: (своего рода стек)
Когда я хочу разрушить, я уничтожаю свои ресурсы> Мой супер уничтожает свои ресурсы.
В этом смысле это применимо к любой паре функций (onCreate / onDestroy, onResume / onPause, onStart / onStop). Естественно, onCreate создаст ресурсы, а onDestroy освободит эти ресурсы. Кстати, то же доказательство применимо и к другим парам.
Давайте рассмотрим загруженную вами библиотеку, которая имеет LocationActivity, который содержит функцию getLocation (), которая определяет местоположение. Скорее всего, для этого действия нужно будет инициализировать его содержимое в onCreate (), что заставит вас сначала вызвать super.onCreate. Вы уже делаете это, потому что чувствуете, что это имеет смысл. Теперь в своем onDestroy вы решаете, что хотите сохранить Location где-нибудь в SharedPreferences. Если вы сначала вызываете super.onDestroy, до некоторой степени возможно, что getLocation вернет нулевое значение после этого вызова, потому что реализация LocationActivity обнуляет значение местоположения в onDestroy. Идея в том, что вы не будете винить это, если это произойдет. Следовательно, вы должны вызвать super.onDestroy в конце после того, как вы закончите свой собственный 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
extends BaseActivity, а позже, я хочу создать SherifElKhatibActivity
, расширяет вашу активность? В каком порядке мне вызывать super.do
функции? В конечном итоге это одно и то же.
Что касается вашего вопроса:
Я думаю, что намерение Google состоит в том, чтобы сказать нам: пожалуйста, звоните суперу, где бы то ни было. В качестве общей практики, конечно, называйте это вначале. У Google, конечно же, самые блестящие инженеры и разработчики, поэтому они, вероятно, хорошо поработали, изолировав свои супервызовы и не вмешиваясь в дочерние вызовы.
Я немного попробовал, и, вероятно, непросто (поскольку мы пытаемся доказать, что ошибается Google) создать действие, которое просто вылетало из-за вызова When, 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 для отправки 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) {
startActivity(new Intent(this, GoodBye.class));
}
}
Если вы вызовете super.onDestroy в начале своего onDestroy, действие GoodBye будет запущено. Если вы вызовете super.onDestroy в конце вашего onDestroy, действие GoodBye не будет запущено.
Конечно, это опять же не лучший пример. Однако это показывает, что Google здесь немного напортачил. Любая из других переменных не повлияла бы на поведение вашего приложения. Однако добавление этой отправки в onDestroy привело к тому, что super каким-то образом помешал вашему подклассу.
Я говорю, что они напортачили и по другой причине. Они не только (до api 14) касались в супер-вызовах только того, что является окончательным и / или закрытым, но они также вызывали различные внутренние функции (частные), которые действительно затем отправляли функции 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;
}
Обратите внимание, что они вызывают onStop действия где-то в этой функции. Следовательно, они могли бы также поместить весь код (включенный в super.onStop) до или после вызова onStop, а затем просто уведомить подклассы об onStop, используя пустые суперфункции onStop и даже не добавляя SuperNotCalledException или проверяя это вызванное.
Для этого, если бы они вызвали эту отправку ActivityLifeCycle в performDestroy вместо того, чтобы вызывать ее в конце super.onDestroy, поведение нашей активности было бы таким же, независимо от того, когда мы действительно вызывали super.
Во всяком случае, это первое, что они делают (немного не так), и это только в API 14.