Süper onCreate'i aramak mantıklı olduğundan (söylediğinizden): Bir düşünün.
Yaratmak istediğimde süperim kaynaklarını yaratır> Kaynaklarımı ben yaratırım.
Tersine: (bir yığın türü)
Yok etmek istediğimde kaynaklarımı yok ederim> Süperim kaynaklarını yok eder.
Bu anlamda, herhangi bir çift işlev için geçerlidir (onCreate / onDestroy, onResume / onPause, onStart / onStop). Doğal olarak, onCreate kaynaklar yaratacak ve onDestroy bu kaynakları serbest bırakacaktır. Bu arada, aynı kanıt diğer çiftler için de geçerli.
İndirdiğiniz, konumu sağlayan bir getLocation () işlevi içeren bir LocationActivity'ye sahip bir kitaplığı düşünelim. Büyük olasılıkla, bu etkinliğin onCreate () içindeki öğelerini başlatması gerekecek ve bu da sizi önce super.onCreate'i çağırmaya zorlayacaktır. Bunu zaten yapıyorsun çünkü mantıklı olduğunu hissediyorsun. Şimdi, onDestroy'unuzda, Konumu Paylaşılan Tercihler'de bir yere kaydetmeye karar veriyorsunuz. Önce super.onDestroy'u çağırırsanız, belirli bir dereceye kadar getLocation'ın bu çağrıdan sonra boş bir değer döndürmesi mümkündür, çünkü LocationActivity uygulaması onDestroy'daki konum değerini geçersiz kılar. Buradaki fikir, bu olursa onu suçlamamanızdır. Bu nedenle, kendi onDestroy ile işiniz bittikten sonra super.onDestroy'u çağırırsınız. Umarım bu biraz mantıklıdır.
Yukarıdakiler mantıklıysa, her an yukarıdaki konsepte uyan bir faaliyetimiz olduğunu düşünün. Bu aktiviteyi genişletmek istersem, muhtemelen aynı şekilde hissedeceğim ve aynı argüman nedeniyle aynı sıralamayı izleyeceğim.
Tümevarım yoluyla, herhangi bir aktivite aynı şeyi yapmalıdır. İşte bu kurallara uymaya zorlanan bir aktivite için iyi bir soyut sınıf:
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);
}
}
Son olarak, adındaki etkinliğiniz AnudeepBullaActivity
BaseActivity'yi genişletirse ve daha sonra, SherifElKhatibActivity
etkinliğinizi genişleten bir etkinlik oluşturmak istersem ? super.do
Fonksiyonları hangi sırayla çağırmalıyım ? Sonuçta aynı şey.
Sorunuza gelince:
Sanırım Google'ın niyetinin bize şunu söylemek olduğunu düşünüyorum: Lütfen nerede olursa olsun kapıcıyı arayın. Tabii ki genel bir uygulama olarak başlangıçta deyin. Google elbette en parlak mühendislere ve geliştiricilere sahiptir, bu yüzden muhtemelen süper çağrılarını izole ederek ve çocuk çağrılarına müdahale etmeden iyi bir iş çıkardılar.
Biraz denedim ve muhtemelen (Google olduğu için yanlış olduğunu kanıtlamaya çalışıyoruz), When is super denildiği için basit bir şekilde çökecek bir aktivite oluşturmak kolay değil.
Neden?
Bu işlevlerde yapılan her şey, Activity sınıfına gerçekten özeldir ve alt sınıfınızla hiçbir zaman çatışmaya neden olmaz. Örneğin (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 ve mManagedDialogs ve mSearchManager özel alanlardır. Ve herkese açık / korunan api'lerin hiçbiri burada yapılanlardan etkilenmeyecektir.
Ancak API 14'te, uygulamanıza kayıtlı ActivityLifecycleCallbacks'e onActivityDestroyed göndermek için dispatchActivityDestroyed eklenmiştir. Bu nedenle, ActivityLifecycleCallback'lerinizdeki bazı mantığa bağlı olan herhangi bir kod, süper kişiyi ne zaman aradığınıza bağlı olarak farklı bir sonuca sahip olacaktır. Örneğin:
Halihazırda çalışan etkinliklerin sayısını sayan bir Uygulama Sınıfı oluşturun:
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) {}
}
Aşağıdakiler bir anlam ifade etmeyebilir veya iyi bir uygulama olmayabilir, ancak sadece bir noktayı kanıtlamak içindir (Kişi daha gerçek bir durum bulabilir). Bittiğinde ve son etkinlik olduğunda GoodBye etkinliğine gittiği varsayılan MainActivity'yi oluşturun:
@Override
protected void onDestroy() {
super.onDestroy();
if(((SherifApplication) getApplication()).getCount() == 0) {
startActivity(new Intent(this, GoodBye.class));
}
}
OnDestroy'unuzun başlangıcında super.onDestroy'u çağırırsanız, GoodBye etkinliği başlatılır. OnDestroy'unuzun sonunda super.onDestroy'u çağırırsanız, GoodBye etkinliği başlatılmaz.
Tabii ki yine, bu optimal örnek değil. Ancak bu, Google'ın burada biraz karışıklık yaptığını gösteriyor. Diğer değişkenlerden herhangi biri uygulamanızın davranışını etkilemezdi. Ancak bu gönderiyi onDestroy'a eklemek süperin alt sınıfınıza bir şekilde müdahale etmesine neden oldu.
Farklı bir sebepten dolayı da berbat ettiklerini söylüyorum. Sadece (api 14'ten önce) süper aramalarda nihai ve / veya özel olana dokunmakla kalmadılar, aynı zamanda onPause ... işlevlerini gerçekten gönderen farklı dahili işlevler (özel) olarak da adlandırdılar.
Örneğin, performStop
işlev, sırayla onStop işlevini çağıran işlevdir:
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;
}
Bu işlevde bir yerde Activity's onStop olarak adlandırdıklarına dikkat edin. Bu nedenle, tüm kodu (super.onStop içinde bulunan) onStop çağrısından önce veya sonra koymuş olabilirler ve ardından boş onStop süper işlevlerini kullanarak ve hatta SuperNotCalledException eklemeden veya çağrıyı kontrol etmeden onStop hakkında alt sınıfları bilgilendirebilirler.
Bunun için bu gönderiyi super.onDestroy'un sonunda çağırmak yerine performDestroy'daki ActivityLifeCycle'a çağırsalar, süper'i ne zaman çağırdığımıza bakılmaksızın etkinliğimizin davranışı aynı olurdu.
Her neyse, yaptıkları ilk şey bu (biraz yanlış) ve sadece API 14'te.