(당신이 말했듯이) super onCreate를 먼저 호출하는 것이 합리적이므로 생각해보십시오.
내가 만들고 싶을 때, 내 수퍼가 리소스를 생성하고> 내 리소스를 생성합니다.
반대로 : (일종의 스택)
내가 파괴하고 싶을 때, 나는 내 자원을 파괴합니다.> 나의 수퍼가 그의 자원을 파괴합니다.
이러한 의미에서 두 가지 함수 (onCreate / onDestroy, onResume / onPause, onStart / onStop)에 적용됩니다. 당연히 onCreate는 리소스를 생성하고 onDestroy는 이러한 리소스를 해제합니다. 그건 그렇고, 다른 커플에게도 같은 증거가 적용됩니다.
위치를 제공하는 getLocation () 함수를 포함하는 LocationActivity가있는 다운로드 한 라이브러리를 고려해 보겠습니다. 아마도이 액티비티는 onCreate ()에서 항목을 초기화해야 할 것입니다. 그러면 super.onCreate를 먼저 호출해야합니다. 당신은 그것이 의미가 있다고 느끼기 때문에 이미 그렇게하고 있습니다. 이제 onDestroy에서 SharedPreferences 어딘가에 위치를 저장하기로 결정했습니다. super.onDestroy를 먼저 호출하면 LocationActivity의 구현이 onDestroy의 위치 값을 무효화하기 때문에 getLocation이이 호출 후에 null 값을 반환 할 가능성이 어느 정도 있습니다. 아이디어는 이런 일이 발생해도 당신이 그것을 비난하지 않을 것이라는 것입니다. 따라서 자신의 onDestroy를 완료 한 후 마지막에 super.onDestroy를 호출합니다. 나는 이것이 약간 의미가 있기를 바랍니다.
위의 내용이 타당하다면 언제든지 위의 개념을 준수하는 활동이 있다는 것을 고려하십시오. 이 활동을 확장하고 싶다면, 똑같은 주장 때문에 같은 방식으로 느끼고 같은 순서를 따를 것입니다.
귀납법으로 모든 활동은 똑같은 일을해야합니다. 다음은 이러한 규칙을 따라야하는 활동에 대한 좋은 추상 클래스입니다.
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);
}
}
마지막으로,라는 활동이 AnudeepBullaActivity
BaseActivity를 확장하고 나중에 SherifElKhatibActivity
활동을 확장하는 것을 만들고 싶습니다 . super.do
함수를 어떤 순서로 호출해야 합니까? 궁극적으로 같은 것입니다.
질문 :
Google의 의도는 다음과 같이 말하는 것 같습니다. 어디에 있든 상관없이 수퍼에 전화하십시오. 물론 일반적인 관행으로 처음에는 호출하십시오. 물론 Google에는 가장 뛰어난 엔지니어와 개발자가 있으므로 그들은 아마도 슈퍼 통화를 분리하고 어린이 통화를 방해하지 않는 좋은 작업을 수행했을 것입니다.
나는 조금 시도했지만 When is super가 호출되기 때문에 간단하게 충돌하는 활동을 만드는 것이 (Google이기 때문에 우리가 잘못 증명하고 있기 때문에) 쉽지 않을 것입니다.
왜?
이 함수에서 수행되는 모든 작업은 실제로 Activity 클래스에만 적용되며 하위 클래스와 충돌을 일으키지 않습니다. 예 : (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 및 mSearchManager는 모두 개인 필드입니다. 그리고 공개 / 보호 된 API는 여기서 수행되는 작업에 영향을받지 않습니다.
그러나 API 14에서는 애플리케이션에 등록 된 ActivityLifecycleCallbacks에 onActivityDestroyed를 디스패치하기 위해 dispatchActivityDestroyed가 추가되었습니다. 따라서 ActivityLifecycleCallbacks의 일부 논리에 의존하는 코드는 super를 호출하는시기에 따라 다른 결과를 갖습니다. 예를 들면 :
현재 실행중인 활동의 수를 계산하는 애플리케이션 클래스를 만듭니다.
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) {}
}
다음은 말이되지 않거나 좋은 관행이 아닐 수도 있지만 단지 요점을 증명하기위한 것입니다 (더 실제 상황을 찾을 수 있음). GoodBye 활동이 완료되고 마지막 활동 일 때 이동하는 MainActivity를 만듭니다.
@Override
protected void onDestroy() {
super.onDestroy();
if(((SherifApplication) getApplication()).getCount() == 0) {
startActivity(new Intent(this, GoodBye.class));
}
}
onDestroy를 시작할 때 super.onDestroy를 호출하면 GoodBye 활동이 시작됩니다. onDestroy가 끝날 때 super.onDestroy를 호출하면 GoodBye 활동이 시작되지 않습니다.
물론 이것은 최적의 예가 아닙니다. 그러나 이것은 Google이 여기서 약간 엉망임을 보여줍니다. 다른 변수는 앱의 동작에 영향을주지 않았습니다. 그러나 이러한 디스패치를 onDestroy에 추가하면 수퍼가 어떻게 든 하위 클래스를 방해합니다.
나는 그들이 다른 이유로도 엉망이라고 말합니다. 그들은 (api 14 이전에) 최종 및 / 또는 비공개 인 슈퍼 호출 만 터치했을뿐만 아니라 실제로 onPause ... 함수를 전달하는 다른 내부 함수 (비공개)를 호출했습니다.
예를 들어 performStop
function은 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;
}
이 함수에서 Activity의 onStop을 호출합니다. 따라서 그들은 onStop에 대한 호출 전후에 모든 코드 (super.onStop에 포함됨)를 넣은 다음 빈 onStop 슈퍼 함수를 사용하고 SuperNotCalledException을 추가하거나이 호출을 확인하지 않고도 onStop에 대해 하위 클래스에 알릴 수 있습니다.
이를 위해 super.onDestroy의 끝에서 호출하는 대신 performDestroy의 ActivityLifeCycle에이 디스패치를 호출하면 super를 호출 한시기에 관계없이 활동의 동작이 동일했을 것입니다.
어쨌든 이것은 그들이하는 첫 번째 일이며 (약간 잘못되었습니다) API 14에만 있습니다.