Оскільки (ви кажете) має сенс спершу назвати super onCreate: подумайте.
Коли я хочу творити, Мій супер створює свої ресурси> Я створюю свої ресурси.
І навпаки: (сорт стека)
Коли я хочу знищити, я знищую свої ресурси> Мій супер знищує його ресурси.
У цьому сенсі це стосується будь-якої пари функцій (onCreate / onDestroy, onResume / onPause, onStart / onStop). Природно, onCreate створить ресурси, а onDestroy звільнить ці ресурси. До речі, той самий доказ стосується інших пар.
Давайте розглянемо завантажену вами бібліотеку, яка має LocationActivity, що містить функцію getLocation (), яка забезпечує розташування. Швидше за все, для цієї діяльності потрібно буде ініціалізувати свої матеріали в onCreate (), що змусить вас викликати спочатку super.onCreate. Ви вже робите це, бо відчуваєте, що це має сенс. Тепер у своєму onDestroy ви вирішили зберегти місце розташування десь у 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
розширює BaseActivity і пізніше, я хочу створити, SherifElKhatibActivity
що розширює вашу діяльність? У якому порядку слід викликати super.do
функції? Зрештою це одне і те ж.
Щодо вашого запитання:
Я думаю, що намір Google полягає в тому, щоб сказати нам: Будь ласка, телефонуйте супермережею незалежно від того, де. Як звичайну практику, звичайно, називайте це спочатку. Звичайно, у Google є найрозумніші інженери та розробники, тому вони, мабуть, добре зробили, ізолюючи свої супер дзвінки та не втручаючись у дзвінки дитини.
Я трохи спробував, і, мабуть, непросто (оскільки ми намагаємося довести, що помиляємося в Google), створити таку діяльність, яка б просто збилася через те, коли викликається супер.
Чому?
Все, що робиться в цих функціях, насправді є приватним для класу 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, матиме різні результати залежно від того, коли ви телефонуєте супер. Наприклад:
Створіть клас програми, який підраховує кількість поточно виконуваних дій:
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 призвело до того, що супер якось заважав вашому підкласу.
Я кажу, що вони зіпсувались і з іншої причини. Вони не тільки (до 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;
}
Зверніть увагу, що вони викликають Activity's onStop десь у цій функції. Тому вони могли б також розмістити весь код (включений у super.onStop) до або після виклику onStop, а потім просто повідомити підкласи про onStop, використовуючи порожні супер функції SuperStop, і навіть не додаючи SuperNotCalledException або перевіряючи це.
Для цього, якби вони викликали цю диспетчерику до ActivityLifeCycle у perforDestroy, замість того, щоб викликати її в кінці super.onDestroy, поведінка нашої діяльності була б однаковою незалежно від того, коли ми називали супер.
У будь-якому випадку це перше, що вони роблять (трохи неправильно), і це лише в API 14.