一時停止・再開への対応 - Dialer (4)

 前回に引き続き、Dialerバージョン1.0.0開発中の話である。懸案の一つであったイタリアの電話番号対応は、前回書いたとおりである。
 もう一つ、Dialerを動かしたまま通話(発信・着信を問わない)が行われると、一部の機種で、通話終了後にDialerが異常終了するという問題が残っていた。MIDletクラスを継承したDialerクラスのコンストラクタの中で主画面となるFormや電話番号などのTextFieldを生成し、Dialer.startApp()メソッドの中でTextFieldをFormにappend()している。Dialerが通話などで一時停止した後ふたたびstartApp()が呼ばれると、すでにForm上に置かれたTextFieldをもう一度同じFormにappend()しようとしてエラーになってしまう。本来は、Dialer.startApp()メソッドが1回目に呼ばれたときだけ、初期化処理を行うようにしておくのが作法である。
 ところで、この部分についての振る舞いは、MIDPの実装によって異なる。ノキアソニー・エリクソンの大部分の機種で採用されている実装では、音声通話その他の割り込みが発生してもMIDletは一時停止状態にならない。そのため、MIDlet.pauseApp()メソッドが呼ばれることはなく、MIDletが再開するときにstartApp()が再度呼ばれることもない。一方、日本メーカーのほとんどの機種で採用されている実装では、先述のように、一時停止と再開のタイミングでpauseApp()メソッドとstartApp()メソッドが呼び出される。筆者は主にソニー・エリクソンの携帯電話でDialerを使うので、初回呼び出しかどうかの判定をさぼっていた。イタリアの電話番号に対応していなかったのとまったく同じ理由である。
 直すのは簡単で、初回呼び出し時にフラグをセットしておき、2回目以降の呼び出しかどうかフラグを検査して判定する。一般には、Displayインスタンスへの参照を保持しているかどうかで判定を行うことが多いようだ。

  private Display display;

  protected  void startApp() {
    if (display == null) {
      display = Display.getDisplay(this);

      // 初期化
        :
        :
    }
  }

 Dialerもこの方法を使っている。