Gingerbreadのトリビア: Activity.onPause()
Gingerbreadのandroid.app.Activity.javaのソースを見ていて気がついたことがあります。
アプリケーションはActivityを継承して作りますが、onCreateやonStartではその中でsuper.onCreateやsuper.onStartを呼ばなくてはならないルールになっています。それをしないと実行時にSuperNotCalledExceptionがスローされてしまいますが、それはこんな仕組みになっていました。
final void performStart() { mCalled = false; mInstrumentation.callActivityOnStart(this); if (!mCalled) { throw new SuperNotCalledException( "Activity " + mComponent.toShortString() + " did not call through to super.onStart()"); } }
mInstrumentation.callActivityOnStart(this)の中で、activity.onStartが呼ばれます。
Activity#onStart は実はこれだけ。
protected void onStart() { mCalled = true; }
チェックのためのチェックかよ!と突っ込み入れたくなります。
同じソースで以下のような不思議な部分を見つけました。
final void performPause() { mCalled = false; onPause(); if (!mCalled && getApplicationInfo().targetSdkVersion >= android.os.Build.VERSION_CODES.GINGERBREAD) { throw new SuperNotCalledException( "Activity " + mComponent.toShortString() + " did not call through to super.onPause()"); } mResumed = false; }
mCalledがtrueでなくても、アプリケーションがGingerbread以前用のものなら見逃す?
Froyo(Android 2.2)で同じところを見てみると ...
final void performPause() { onPause(); }
おや?ノーチェックだ。
理由があってのことなのか、単なる漏れだったのかわかりませんが、Froyo以前ではonPauseの中でsuper.onPauseを呼ばなくても例外は発生しなかったようです。それをGingerbreadでは他と同じようにチェックするようにしたのですが、過去との互換性のためにアプリケーションがGingerbread以前用にビルドされている場合には見逃すようにしたみたいです。汚いけどそうしておかないと動かないアプリが出てくるだろうから。