Karena (Anda mengatakan) masuk akal untuk memanggil super onCreate terlebih dahulu: Pikirkanlah.
Ketika saya ingin membuat, Super saya menciptakan sumber dayanya> Saya membuat sumber daya saya.
Terbalik: (semacam tumpukan)
Ketika saya ingin menghancurkan, saya menghancurkan sumber daya saya> Super saya menghancurkan sumber dayanya.
Dalam pengertian ini, ini berlaku untuk beberapa fungsi (onCreate / onDestroy, onResume / onPause, onStart / onStop). Secara alami, onCreate akan membuat sumber daya dan onDestroy akan membebaskan sumber daya ini. Ngomong-ngomong, bukti yang sama berlaku untuk pasangan lain.
Mari kita pertimbangkan pustaka yang Anda unduh yang memiliki LocationActivity yang berisi fungsi getLocation () yang menyediakan lokasi. Kemungkinan besar, aktivitas ini perlu menginisialisasi barangnya di onCreate () yang akan memaksa Anda memanggil super.onCreate terlebih dahulu. Anda sudah melakukannya karena Anda merasa itu masuk akal. Sekarang, di onDestroy Anda, Anda memutuskan ingin menyimpan Lokasi di suatu tempat di SharedPreferences. Jika Anda memanggil super.onDestroy terlebih dahulu, sampai batas tertentu mungkin getLocation akan mengembalikan nilai null setelah panggilan ini karena implementasi LocationActivity membatalkan nilai lokasi di onDestroy. Idenya adalah Anda tidak akan menyalahkannya jika ini terjadi. Oleh karena itu, Anda akan memanggil super.onDestroy di bagian akhir setelah Anda selesai dengan onDestroy Anda sendiri. Saya harap ini masuk akal.
Jika hal di atas masuk akal, pertimbangkan bahwa setiap saat kita memiliki aktivitas yang sesuai dengan konsep di atas. Jika saya ingin melanjutkan kegiatan ini, saya mungkin akan merasakan hal yang sama dan mengikuti urutan yang sama karena argumen yang sama persis.
Dengan induksi, aktivitas apapun harus melakukan hal yang sama. Berikut adalah kelas abstrak yang bagus untuk aktivitas yang dipaksa mengikuti aturan ini:
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);
}
}
Terakhir, bagaimana jika aktivitas Anda yang disebut AnudeepBullaActivity
extends BaseActivity dan kemudian, saya ingin membuat SherifElKhatibActivity
yang memperluas aktivitas Anda? Dalam urutan apa saya harus memanggil super.do
fungsi? Itu pada akhirnya adalah hal yang sama.
Adapun pertanyaan Anda:
Saya pikir niat Google adalah memberi tahu kami: Harap hubungi super di mana pun. Sebagai praktik umum tentunya, sebut saja di awal. Google tentu saja memiliki insinyur dan pengembang paling cerdas sehingga mereka mungkin melakukan pekerjaan yang baik dengan mengisolasi panggilan super mereka dan tidak mengganggu panggilan anak.
Saya mencoba sedikit dan mungkin tidak mudah (karena ini adalah Google, kami mencoba untuk membuktikan kesalahan) untuk membuat aktivitas yang akan crash sederhana karena When is super sedang dipanggil.
Mengapa?
Apa pun yang dilakukan dalam fungsi ini benar-benar pribadi untuk kelas Aktivitas dan tidak akan pernah menimbulkan konflik dengan subkelas Anda. Misalnya (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 dan mManagedDialogs serta mSearchManager semuanya adalah bidang pribadi. Dan tidak ada api publik / dilindungi yang akan terpengaruh oleh apa yang dilakukan di sini.
Namun, dalam API 14, dispatchActivityDestroyed telah ditambahkan untuk mengirimkan onActivityDestroyed ke ActivityLifecycleCallbacks yang terdaftar ke Aplikasi Anda. Oleh karena itu, kode apa pun yang bergantung pada beberapa logika dalam ActivityLifecycleCallbacks Anda akan memiliki hasil yang berbeda berdasarkan pada saat Anda memanggil super. Sebagai contoh:
Buat Kelas Aplikasi yang menghitung jumlah aktivitas yang sedang berjalan:
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) {}
}
Berikut ini mungkin tidak masuk akal atau bukan praktik yang baik tetapi ini hanya untuk membuktikan suatu hal (Orang mungkin menemukan situasi yang lebih nyata). Buat MainActivity yang seharusnya masuk ke aktivitas GoodBye saat selesai dan saat itu adalah aktivitas terakhir:
@Override
protected void onDestroy() {
super.onDestroy();
if(((SherifApplication) getApplication()).getCount() == 0) {
startActivity(new Intent(this, GoodBye.class));
}
}
Jika Anda memanggil super.onDestroy di awal onDestroy, aktivitas GoodBye akan diluncurkan. Jika Anda memanggil super.onDestroy di akhir onDestroy Anda, aktivitas GoodBye tidak akan diluncurkan.
Tentu saja, sekali lagi, ini bukan contoh yang optimal. Namun ini menunjukkan bahwa Google sedikit kacau di sini. Variabel lain mana pun tidak akan memengaruhi perilaku aplikasi Anda. Namun menambahkan pengiriman ini ke onDestroy menyebabkan super mengganggu subkelas Anda.
Saya mengatakan mereka mengacaukan karena alasan yang berbeda juga. Mereka tidak hanya (sebelum api 14) hanya menyentuh panggilan super apa yang final dan / atau pribadi, tetapi mereka juga memanggil fungsi internal yang berbeda (pribadi) yang kemudian mengirimkan fungsi onPause ....
Misalnya, performStop
fungsi adalah fungsi yang dipanggil yang pada gilirannya memanggil fungsi 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;
}
Perhatikan bahwa mereka memanggil onStop Aktivitas di suatu tempat dalam fungsi ini. Oleh karena itu, mereka mungkin sebaiknya meletakkan semua kode (termasuk dalam super.onStop) sebelum atau setelah panggilan ke onStop dan kemudian memberi tahu subclass tentang onStop menggunakan fungsi super onStop kosong dan bahkan tanpa menambahkan SuperNotCalledException atau memeriksa panggilan ini.
Untuk ini, jika mereka memanggil pengiriman ini ke ActivityLifeCycle di performDestroy alih-alih memanggilnya di akhir super.onDestroy, perilaku aktivitas kita akan sama terlepas dari kapan kita memanggil super.
Bagaimanapun ini adalah hal pertama yang mereka lakukan (agak salah) dan hanya di API 14.