(あなたが言う)最初にsuper onCreateを呼び出すのは理にかなっているので、考えてみてください。
作成したいときは、スーパーがリソースを作成します>リソースを作成します。
逆に:(スタックの一種)
破壊したいときは、リソースを破壊します>スーパーは彼のリソースを破壊します。
この意味で、これは任意の2つの関数(onCreate / onDestroy、onResume / onPause、onStart / onStop)に適用されます。当然、onCreateはリソースを作成し、onDestroyはこれらのリソースを解放します。ちなみに、同じ証明が他のカップルにも当てはまります。
ロケーションを提供するgetLocation()関数を含むLocationActivityを含むダウンロードしたライブラリを考えてみましょう。ほとんどの場合、このアクティビティは、onCreate()でその内容を初期化する必要があるため、最初にsuper.onCreateを呼び出す必要があります。あなたはそれが理にかなっていると感じるのであなたはすでにそれをしています 次に、onDestroyで、Locationを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がsuperが呼び出されているために単純にクラッシュするアクティビティを作成することはおそらく簡単ではありません(Googleであるため、間違っていることを証明しようとしています)。
どうして?
これらの関数で実行されることはすべて、Activityクラスに対してプライベートであり、サブクラスとの競合を引き起こすことはありません。たとえば(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およびmManagedDialogsとmSearchManagerはすべてプライベートフィールドです。また、パブリック/保護されたAPIは、ここで行われることの影響を受けません。
ただし、API 14では、アプリケーションに登録されているActivityLifecycleCallbacksにonActivityDestroyedをディスパッチするためにdispatchActivityDestroyedが追加されました。したがって、ActivityLifecycleCallbacksのロジックに依存するコードは、スーパーを呼び出すタイミングに基づいて異なる結果になります。例えば:
現在実行中のアクティビティの数をカウントするアプリケーションクラスを作成します。
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) {
//i want to go to a certain activity when there are no other activities
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;
}
この関数のどこかでアクティビティのonStopを呼び出していることに注意してください。したがって、onStopの呼び出しの前または後にすべてのコード(super.onStopに含まれている)を配置して、空のonStopスーパー関数を使用し、SuperNotCalledExceptionを追加したり、呼び出されたことを確認したりせずに、onStopについてサブクラスに通知するだけの場合もあります。
このため、super.onDestroyの最後に呼び出すのではなく、performDestroyでこのディスパッチをActivityLifeCycleに呼び出した場合、スーパーを呼び出したタイミングに関係なく、アクティビティの動作は同じになります。
とにかく、これは彼らが最初に行うこと(少し間違っています)であり、API 14でのみ発生します。