Depuis (vous dites) il est logique d'appeler super onCreate première: Pensez à ce sujet.
Lorsque je veux créer Mon super crée ses ressources > j'ai créer mes ressources.
Inversement: (une sorte de pile)
Quand je veux me détruire, je détruis mes ressources > Mon super détruit ses ressources.
En ce sens, il s'applique à tout couple de fonctions (onCreate/onDestroy, onResume/onPause, onStart/onStop). Naturellement, onCreate permettra de créer des ressources et des onDestroy permettra de libérer ces ressources. Par ailleurs, la même preuve s'applique pour les autres couples.
Considérons une bibliothèque que vous avez téléchargé qui a un LocationActivity qui contient un getLocation() fonction qui fournit l'emplacement. Plus probablement, cette activité devra initialiser ses trucs dans le onCreate() qui va vous forcer à appeler le super.onCreate de la première. Vous avez déjà le faire parce que vous vous sentez cela a du sens. Maintenant, dans votre onDestroy, vous décidez que vous voulez enregistrer l'Emplacement quelque part dans les SharedPreferences. Si vous appelez super.onDestroy tout d'abord, il est, dans une certaine mesure du possible que les getLocation retourne une valeur null après cet appel, car la mise en œuvre de LocationActivity annule l'emplacement de la valeur dans le onDestroy. L'idée est que vous ne le blâme pas, si cela arrive. Par conséquent, vous pouvez appeler super.onDestroy à la fin après que vous avez terminé avec votre propre onDestroy. J'espère que ce qui fait un peu de sens.
Si les sens, considérer que, à tout moment, nous avons une activité qui respecte le concept ci-dessus. Si je veux prolonger cette activité, je vais probablement sentir de la même manière et suivent la même commande en raison d'exactement le même argument.
Par induction, toute activité doit faire la même chose. Voici un bon résumé de la classe pour une activité forcée de suivre ces règles:
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);
}
}
Enfin, que faire si votre activité est appelée AnudeepBullaActivity
s'étend BaseActivity et plus tard, je veux créer SherifElKhatibActivity
qui s'étend de votre activité? Dans quel ordre dois-je appeler l' super.do
fonctions? C'est finalement la même chose.
Quant à votre question:
Je pense que Google a l'intention de nous dire: Veuillez appeler le super n'importe où. En tant que pratique générale bien sûr, appelez ça au début. Google a bien sûr les plus brillants, les ingénieurs et les développeurs afin qu'ils probablement fait un bon travail en isolant leur super appels et de ne pas interférer dans l'enfant des appels.
J'ai essayé un peu, et ça n'est probablement pas facile (puisque c'est Google nous essayons de prouver la mauvaise) pour créer une activité qui serait panne simple Quand est super d'être appelé.
Pourquoi?
Tout ce qui est fait de ces fonctions est vraiment privé à l'Activité de la classe et ne serait jamais provoquer un conflit avec votre sous-classe. Par exemple (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 et mManagedDialogs et mSearchManager sont tous les champs privés. Et aucun des public/protected api seront touchés par ce qui est fait ici.
Toutefois, l'API 14, dispatchActivityDestroyed a été ajouté à l'envoi d'une onActivityDestroyed à la ActivityLifecycleCallbacks inscrit à votre Demande. Par conséquent, tout code qui dépendra un peu de logique dans votre ActivityLifecycleCallbacks aura un résultat différent en fonction du moment où vous êtes l'appel de la super. Par exemple:
Créer une Application de Classe qui compte le nombre de actuellement en cours d'exécution des activités:
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) {}
}
La suite n'aurait pas de sens ou n'est pas une bonne pratique, mais c'est juste pour prouver un point (que l'On pourrait trouver un plus réel de la situation). Créer le MainActivity qui va de soi-disant au Revoir à l'activité, quand c'est fini et quand il s'agit de la dernière activité:
@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));
}
}
Si vous appelez super.onDestroy dans le début de votre onDestroy, l'au Revoir de l'activité sera lancée. Si vous appelez super.onDestroy à la fin de votre onDestroy, l'au Revoir de l'activité ne sera pas lancé.
Bien sûr, encore une fois, ce n'est pas la meilleure exemple. Toutefois, cela montre que Google foiré un peu ici. L'un des autres variables seraient pas touchés de votre application à un comportement. Cependant, l'ajout de ces dispatcher le onDestroy causé la super de faire en quelque sorte interférer avec votre sous-classe.
Je dis " ils ont foiré pour une autre raison. Non seulement ont-ils (avant api 14), seulement dans le super appels de ce qui est finale et/ou privé, mais ils ont également appelé les différentes fonctions internes (privé) qui a vraiment ensuite distribué la onPause... fonctions.
Par exemple, performStop
fonction est la fonction appelée, qui à son tour appelle la onStop fonction:
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;
}
Notez qu'ils appellent l'Activité onStop quelque part dans cette fonction. Par conséquent, ils auraient pu aussi bien mettre tout le code (inclus dans super.onStop) avant ou après l'appel à onStop et puis juste informer les sous-classes sur le onStop à l'aide de vide onStop super fonctions et sans même l'ajout de la SuperNotCalledException ou la vérification de ce qui est appelé.
Pour cela, si ils ont appelé cette expédition à l'ActivityLifeCycle dans le performDestroy au lieu de l'appeler à la fin de super.onDestroy, notre activité de comportement aurait été la même, peu importe quand nous avons fait appel à la super.
De toute façon c'est la première chose qu'ils font (un peu de mal) et c'est seulement dans l'API 14.