Ya que (dices) tiene sentido llamar a super onCreate primero: Piénsalo.
Cuando quiero crear, Mi super crea sus recursos> Yo creo mis recursos.
Inversamente: (una especie de pila)
Cuando quiero destruir, destruyo mis recursos> Mi súper destruye sus recursos.
En este sentido, se aplica a cualquier par de funciones (onCreate / onDestroy, onResume / onPause, onStart / onStop). Naturalmente, onCreate creará recursos y onDestroy los liberará. Por cierto, la misma prueba se aplica a las otras parejas.
Consideremos una biblioteca que descargó que tiene una LocationActivity que contiene una función getLocation () que proporciona la ubicación. Lo más probable es que esta actividad necesite inicializar su contenido en onCreate (), lo que te obligará a llamar primero a super.onCreate. Ya lo hace porque siente que tiene sentido. Ahora, en su onDestroy, decide que desea guardar la Ubicación en algún lugar de SharedPreferences. Si llama a super.onDestroy primero, hasta cierto punto es posible que getLocation devuelva un valor nulo después de esta llamada porque la implementación de LocationActivity anula el valor de ubicación en onDestroy. La idea es que no lo culparías si esto sucediera. Por lo tanto, llamaría super.onDestroy al final después de que haya terminado con su propio onDestroy. Espero que esto tenga un poco de sentido.
Si lo anterior tiene sentido, considere que en cualquier momento tenemos una actividad que se apega al concepto anterior. Si quiero extender esta actividad, probablemente sentiré lo mismo y seguiré el mismo orden debido al mismo argumento exacto.
Por inducción, cualquier actividad debería hacer lo mismo. Aquí hay una buena clase abstracta para una actividad obligada a seguir estas reglas:
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);
}
}
Finalmente, ¿qué AnudeepBullaActivity
pasa si tu actividad llamada extiende BaseActivity y luego quiero crear SherifElKhatibActivity
que amplíe tu actividad? ¿En qué orden debo llamar a las super.do
funciones? En última instancia, es lo mismo.
En cuanto a tu pregunta:
Creo que la intención de Google es decirnos: por favor, llame al superintendente sin importar dónde. Como práctica general, por supuesto, llámelo al principio. Google, por supuesto, tiene los ingenieros y desarrolladores más brillantes, por lo que probablemente hicieron un buen trabajo al aislar sus super llamadas y no interferir en las llamadas de los niños.
Intenté un poco y probablemente no sea fácil (ya que es Google lo que estamos tratando de demostrar que estamos equivocados) crear una actividad que se bloquee de manera simple debido a la llamada de When is super.
¿Por qué?
Todo lo que se haga en estas funciones es realmente privado para la clase Activity y nunca causaría ningún conflicto con su subclase. Por ejemplo (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 y mManagedDialogs y mSearchManager son todos campos privados. Y ninguna de las API públicas / protegidas se verá afectada por lo que se haga aquí.
Sin embargo, en la API 14, dispatchActivityDestroyed se agregó para enviar un onActivityDestroyed a ActivityLifecycleCallbacks registrados en su aplicación. Por lo tanto, cualquier código que dependa de alguna lógica en su ActivityLifecycleCallbacks tendrá un resultado diferente en función de cuándo llame al super. Por ejemplo:
Cree una clase de aplicación que cuente el número de actividades en ejecución actualmente:
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) {}
}
Lo siguiente puede no tener sentido o no es una buena práctica, pero es solo para probar un punto (uno podría encontrar una situación más real). Cree la MainActivity que supuestamente va a la actividad GoodBye cuando finaliza y cuando es la última actividad:
@Override
protected void onDestroy() {
super.onDestroy();
if(((SherifApplication) getApplication()).getCount() == 0) {
startActivity(new Intent(this, GoodBye.class));
}
}
Si llama a super.onDestroy al comienzo de su onDestroy, se iniciará la actividad Adiós. Si llama a super.onDestroy al final de su onDestroy, la actividad Adiós no se iniciará.
Por supuesto, nuevamente, este no es el ejemplo óptimo. Sin embargo, esto muestra que Google se equivocó un poco aquí. Cualquiera de las otras variables no habría afectado el comportamiento de su aplicación. Sin embargo, agregar estos envíos a onDestroy causó que el súper interfiriera de alguna manera con su subclase.
Yo digo que también se metieron por una razón diferente. No solo (antes de la API 14) solo tocaron en las super llamadas lo que es final y / o privado, sino que también llamaron a diferentes funciones internas (privadas) que realmente luego enviaron las funciones onPause ...
Por ejemplo, performStop
function es la función llamada que a su vez llama a la función 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;
}
Observe que llaman a la actividad onStop en algún lugar de esta función. Por lo tanto, también podrían haber puesto todo el código (incluido en super.onStop) antes o después de la llamada a onStop y luego simplemente notificar a las subclases sobre el onStop usando superfunciones onStop vacías y sin siquiera agregar SuperNotCalledException o verificar esta llamada.
Por esto, si llamaron a este envío a ActivityLifeCycle en performDestroy en lugar de llamarlo al final de super.onDestroy, el comportamiento de nuestra actividad habría sido el mismo independientemente de cuándo llamamos al super.
De todos modos esto es lo primero que hacen (un poco mal) y es solo en API 14.