Dal momento che (dici) ha senso chiamare prima super onCreate: pensaci.
Quando voglio creare, il mio super crea le sue risorse> io creo le mie risorse.
Inversamente: (una specie di pila)
Quando voglio distruggere, distruggo le mie risorse> Il mio super distrugge le sue risorse.
In questo senso, si applica a qualsiasi coppia di funzioni (onCreate / onDestroy, onResume / onPause, onStart / onStop). Naturalmente, onCreate creerà risorse e onDestroy libererà queste risorse. A proposito, la stessa prova vale per le altre coppie.
Si consideri una libreria scaricata che ha una LocationActivity che contiene una funzione getLocation () che fornisce la posizione. Molto probabilmente, questa attività dovrà inizializzare il suo contenuto in onCreate () che ti costringerà a chiamare prima super.onCreate. Lo fai già perché senti che ha senso. Ora, nel tuo onDestroy, decidi di salvare la posizione da qualche parte nelle SharedPreferences. Se chiami prima super.onDestroy, è in una certa misura possibile che getLocation restituisca un valore nullo dopo questa chiamata perché l'implementazione di LocationActivity annulla il valore di posizione in onDestroy. L'idea è che non lo biasimeresti se ciò accadesse. Pertanto, chiameresti super.onDestroy alla fine dopo aver finito con il tuo onDestroy. Spero che questo abbia un senso.
Se quanto sopra ha senso, considera che in qualsiasi momento abbiamo un'attività che si attiene al concetto di cui sopra. Se voglio estendere questa attività, probabilmente mi sentirò allo stesso modo e seguirò lo stesso ordine a causa dello stesso identico argomento.
Per induzione, qualsiasi attività dovrebbe fare la stessa cosa. Ecco una buona lezione astratta per un'attività costretta a seguire queste regole:
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);
}
}
Infine, cosa succede se la tua attività chiamata AnudeepBullaActivity
estende BaseActivity e in seguito voglio creare SherifElKhatibActivity
che estenda la tua attività? In quale ordine devo chiamare le super.do
funzioni? In definitiva è la stessa cosa.
Per quanto riguarda la tua domanda:
Penso che l'intenzione di Google sia di dirci: chiama il super, non importa dove. Come pratica generale, ovviamente, chiamala all'inizio. Google ovviamente ha gli ingegneri e gli sviluppatori più brillanti, quindi probabilmente hanno fatto un buon lavoro isolando le loro super chiamate e non interferendo con le chiamate dei bambini.
Ho provato un po 'e probabilmente non è facile (dato che è Google che stiamo cercando di dimostrare che si sbaglia) creare un'attività che si arresti facilmente a causa di quando viene chiamato super.
Perché?
Qualunque cosa fatta in queste funzioni è veramente privata per la classe Activity e non causerebbe mai alcun conflitto con la tua sottoclasse. Ad esempio (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 e mSearchManager sono tutti campi privati. E nessuna delle API pubbliche / protette sarà influenzata da ciò che viene fatto qui.
Tuttavia, nell'API 14, dispatchActivityDestroyed è stato aggiunto per inviare un onActivityDestroyed agli ActivityLifecycleCallback registrati nella tua applicazione. Pertanto, qualsiasi codice che dipenda da una logica nei tuoi ActivityLifecycleCallbacks avrà un risultato diverso in base a quando chiami il super. Per esempio:
Creare una classe di applicazione che conti il numero di attività attualmente in esecuzione:
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) {}
}
Quanto segue potrebbe non avere senso o non è quello di una buona pratica, ma è solo per dimostrare un punto (si potrebbe trovare una situazione più reale). Crea la MainActivity che presumibilmente va all'attività GoodBye quando è terminata e quando è l'ultima attività:
@Override
protected void onDestroy() {
super.onDestroy();
if(((SherifApplication) getApplication()).getCount() == 0) {
startActivity(new Intent(this, GoodBye.class));
}
}
Se chiami super.onDestroy all'inizio del tuo onDestroy, verrà lanciata l'attività GoodBye. Se chiami super.onDestroy alla fine del tuo onDestroy, l'attività GoodBye non verrà avviata.
Naturalmente, ancora una volta, questo non è l'esempio ottimale. Tuttavia questo mostra che Google ha incasinato un po 'qui. Qualsiasi altra variabile non avrebbe influenzato il comportamento della tua app. Tuttavia, l'aggiunta di queste spedizioni a onDestroy ha causato l'interferenza del super in qualche modo con la tua sottoclasse.
Dico che hanno fatto casino anche per un motivo diverso. Non solo (prima dell'api 14) nelle chiamate super toccavano solo ciò che è final e / o private, ma chiamavano anche diverse funzioni interne (private) che in realtà inviavano le funzioni onPause ...
Ad esempio, performStop
function è la funzione chiamata che a sua volta chiama la funzione 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;
}
Notare che chiamano onStop dell'attività da qualche parte in questa funzione. Pertanto, potrebbero anche aver inserito tutto il codice (incluso in super.onStop) prima o dopo la chiamata a onStop e quindi notificare alle sottoclassi onStop usando super funzioni vuote onStop e senza nemmeno aggiungere SuperNotCalledException o controllare questa chiamata.
Per questo, se avessero chiamato questo invio ad ActivityLifeCycle in performDestroy invece di chiamarlo alla fine di super.onDestroy, il comportamento della nostra attività sarebbe stato lo stesso indipendentemente da quando abbiamo chiamato il super.
Comunque questa è la prima cosa che fanno (un po 'sbagliata) ed è solo nell'API 14.