Mind for Android マニュアル




起動/終了/イベント処理


 このセクションでは、起動、終了ほか、イベント処理全般について解説します。


起動時と終了時の処理

起動
 標準的なMindと同じように、Android版もアプリケーションが立ち上がると処理単語「メイン」が実行されます。
 パッケージの中に複数のアクティビティやサービスがパックされている場合は主アクティビティの「メイン」が実行されます。
 Android版での「メイン」処理は画面の初期描画など、最初に必要な処理のみを実行しただちに終るようにしてください。
 メインの中で長時間かかる処理をおこなわないでください。もしそのようなことがあるとその間、ボタンなどユーザインターフェースに応答しなくなるでしょう(たとえばボタンが押下状態のまま戻らなくなります)。
 データの初期化や初期画面の描画が終わったら直ちに「メイン」から抜け、初期の処理以外は別途イベント・ドリブンで記述してください。
 Android版では何か起きるたびにイベントが発生し、対応するMind単語が呼び出されるので、そちらで対応処理をおこないます。
 そして、イベント処理の中でもまた(メインと同じように)必要な処理をおこなったら直ちに終了してください。
別の章で解説しますが、時間のかかる処理は「スレッド」という機構を使います。
少し時間を待ってから別の処理をおこないたい時は「n秒待ち」ではなく、「遅延実行」という機構を使います。

プログラムの終了
 Android 共通の「戻る」ボタンをクリックすればアプリケーションは終了するため、テストプログラムなどで簡単に作りたいならプログラムを終了するための機構(たとえば「終了」ボタンの設置)は入れなくても使えることは使えます。

    (メイン処理にて)
 標準的なMindでは「メイン」の処理が最後まで(「。」の所まで)到達すると自動的にプログラム終了しましたが、Android版ではメインの最後まで到達しただけではプログラムは終了せず、イベント待ち状態で実行状態が続きます
 特別にメインの中で(エラー検出などで)プログラムを終了させたい場合は大域変数「メインの戻値」に情報を代入し、メイン自身のリターンは通常通りスタックを空にして終了させます(たとえば「終り」の記述)。詳しくは 実行終り定数」を返す方法 にて。

    (イベント処理にて)
 プログラムを明に実行終了させるにはイベント処理の戻値として 定数「実行終り定数 を返します。なお、主アクティビティをプログラム終了させた場合はそのアプリケーション全体が終了しますが、副アクティビティの終了では全体は終了しません。

    (処理単語「実行終り」は無い)
 標準的なMindにあった「実行終り」という処理単語はAndroid版にはありません。

    (プログラム終了する直前に何かさせたい場合)
 プログラムの本当の終了時に、後片付けのような処理をさせるために 実行終り時の処理 という機構が使えます。Androidでは、自らのプログラム処理によるのではなく、たとえばOS標準の「戻る」ボタンによりOSから強制的に終了させられることがあるのでこのような機構は必要になります。


重大エラー(Mindランタイムによるプログラムの強制終了)
 プログラムミスなどでMindのランタイムが異常を検出した時 (配列要素番号異常や、ゼロによる除算など)、「重大エラー」という検出が行われてプログラムは強制終了します。(プログラムで意図的にそれを引き起こすには処理単語「重大エラーにする」を使います)
 重大エラー発生時、それを知らせるために2つの表示が行われます。1つはトースト機能(Mindでは「ちょっと表示」)を使って画面に直接知らせるもの、もう1つはノーティフィケーション(通知機能)による通知です。前者はエラー発生時に短時間表示され、後者は情報が残るため後から調べることができます。

ポップアップ(またはトースト) 通知領域への表示



 上記右側、通知領域への表示では2行目にエラー内容が表示されていますが、ここでは 「ゼロで除算しました」 とあるので、「余り」あるいは「割る」などの除算系の処理単語を呼び出した時に異常検出されたと解釈でき、ソースコードのそのあたりを調べれば良いことになります。


スタックエラー(スタックのずれを検出したときの強制終了)
 Mindのランタイムが異常を検出した時に強制終了するという点で先の「重大エラー」と似ていますが、こちらは特にスタックのずれを検出したときの終了を指します。
 Mindでのプログラム作成にまだ慣れない段階ではプログラムのミスをしがちですが、往々にしてそのようなときスタックのずれが発生します。「スタックのずれ」とは、スタックにデータを過剰に積んでしまうこと、あるいは逆にスタックに必要なデータが積まれていない(データ数が足りない)状態です。
 Mindはその原理上、プログラム中の「ある時点でスタックにどのぐらいのデータが積まれているべきか」は自動的には判別つきません。しかし特定のタイミングで自動把握可能なものもあります。たとえば「メイン」の処理が最後まで到達したときにはスタックは空のはずですし、イベント処理の最後ではスタックには必ずデータ(イベントの戻り値)が1つ積まれているはずです。
 Mindのライブラリタイムはそのような幾つかのタイミングでスタックのずれを自動的に調べ、本来の個数と異なっていることを検出すると、その旨のメッセージを表示してプログラムを強制終了するようになっています。
 スタックエラーが検出されるとそれを知らせるために2つの表示が行われます。1つはトースト機能(Mindでは「ちょっと表示」)を使って画面に直接知らせるもの、もう1つはノーティフィケーション(通知機能)による通知です。前者はエラー発生時に短時間表示され、後者は情報が残るため後から調べることができます。
アプリの操作中に突然落ちたようなケースでは、スタックエラーによることが多いので、念のため下図の表示を確認すると良いでしょう。
ポップアップ(またはトースト) 通知領域への表示



 上記右側、通知領域への表示では2行目にエラー内容が表示されていますが、ここでは 「ボタンクリック処理の後」 とあるので、ボタンクリック処理の中のどこかでスタックずれを起こすような記述になってしまっていると解釈でき(イベント処理の戻値の積み忘れなど)、ソースコードのそのあたりを調べれば良いことになります。


クリック時のイベント処理

■ボタンクリック処理(仮/本定義)
文法
ボタンクリック処理とは 本定義 (ボタンID → 戻値)
記述例(終了ボタンのみ)
※ファイル名	Event/SpEv.src

ボタンクリック処理は	本定義  (ボタンID → 戻値)
		_ボタンは ID	※←このサンプルでは使わない
	_ボタンに 入れ
	実行終り定数を 返す。		※←戻値によりさらなるイベントを発生

メインとは	(・ → ・)
		_レイアウトは	ID
		_ガイド文は	ID
		_ボタン1は	ID
 (レイアウト)
	リニアレイアウトを生成し _レイアウトに 入れ
	垂直を  	_レイアウトに 子の追加方向を設定し
	_レイアウトを レイアウトをアクティビティに追加し
 (ガイド)
	テキストビューを生成し	_ガイド文に 入れ
	18を			_ガイド文に 文字のサイズを設定し
	黒色を			_ガイド文に 文字の色を設定し
	緑色を			_ガイド文に 背景色を設定し
	「ボタンを押すとアクティビティを終了します」を
				_ガイド文に 文字を設定し
	_ガイド文を _レイアウトに ビューを追加し
 (ボタン1)
	ボタンビューを生成し _ボタン1に 入れ
	20を		_ボタン1に 文字のサイズを設定し
	「終了」を	_ボタン1に 文字を設定し
	_ボタン1を _レイアウトに ビューを追加し
	_ボタン1を クリックリスナーを登録する


 上記ソース末尾の 「_ボタン1を クリックリスナーを登録」 により、指定したボタンのクリック時のイベントを受け取れるようにします。
 一方、そのイベントはソース先頭にある 「ボタンクリック処理は 本定義」 でMind側に引き取ることができるので、ここへイベント処理を記述します。
 「ボタンクリック処理」にはボタンIDが渡されるのですが、このサンプルプログラムでは、どのボタンが押されたか、の識別をする必要がないので(ボタンが1つしかないので)ボタンIDは局所変数に格納するものの、使っていません。
 「ボタンクリック処理」の処理の最後では、戻値を1つ積んで帰ることを忘れないでくだこさい(これはすべてのイベント処理に共通の仕様です)。この戻値により、さらに後続のイベントを発生させることができます。このサンプルではプログラムを終了させるために「実行終り定数」を返しています。
 もしイベント処理の中からさらなるイベントを発生させる必要が無いのであれば数値0を返してください。

 次は実際に機能するボタンを使った例です。
記述例(実際に機能するボタン)
※ファイル名	Event/SpEvBcolor.src

色の状態は 2個の 変数。

ボタンクリック処理は	本定義  (ボタンID → 戻値)
		_ボタンは ID
		_番号は  変数
	_ボタンに 入れ
	_ボタンの IDから番号を得て _番号に 入れ
	_番号が 3に 等しい		※←「終了」ボタンのこと
		ならば 実行終り定数を 返し
			終り
		つぎに
	色の状態(_番号)を 一つ増加し
	色の状態(_番号)と 1を ANDし 真?
		ならば 赤色を
		さもなければ
			黄色を
		つぎに
	_ボタンに 文字の色を設定し
	0を 返し。

メインとは	(・ → ・)
		_レイアウトは	ID
		_ガイドは	ID
		_ボタン数は	数値 3
		_ボタンラベルは 文字列定数配列
			「ボタン1」 「ボタン2」 「終了」
		_ボタンは	_ボタン数の ID
 (レイアウト)
	リニアレイアウトを生成し _レイアウトに 入れ
	垂直を  	_レイアウトに 子の追加方向を設定し
	_レイアウトを レイアウトをアクティビティに追加し
 (ガイド)
	テキストビューを生成し	_ガイドに 入れ
	18を			_ガイドに 文字のサイズを設定し
	黒色を			_ガイドに 文字の色を設定し
	緑色を			_ガイドに 背景色を設定し
	「ボタンを押すとボタンの文字の色が変わります」を
				_ガイドに 文字を設定し
	_ガイドを _レイアウトに ビューを追加し
 (ボタン群)
	_ボタン数を
	回数指定し
		ボタンビューを生成し	_ボタン(回数)に 入れ
		20を			_ボタン(回数)に 文字のサイズを設定し
		_ボタンラベル(回数)を
					_ボタン(回数)に 文字を設定し
		_ボタン(回数)を _レイアウトに ビューを追加し
		_ボタン(回数)を クリックリスナーを登録し
	繰り返し。
起動時の画面 ボタン1を一度、ボタン2を二度押したあと



 上のサンプルでは3つのボタンを使いますが、すべてのボタンを「クリックリスナーを登録」し、クリックしたときのイベントを受けられるようにしています。
 イベント処理である「ボタンクリック処理」では、受け取ったボタンIDから「IDから番号を得て」によってその通し番号を抽出し、番号毎に異なった処理をしているのが分かります。


■チェックボックス変化処理(仮/本定義)
文法
チェックボックス変化処理とは 本定義 (ID → 戻値)
記述例
※ファイル名	Event/SpCheckbox.src

チェックボックス変化処理とは	本定義  (ID → 戻値)
		_IDは  ID
		_状態は  変数
		_メッセージは 文字列実体 長さ 80桁
		_バッファは  文字列実体 長さ  1桁
	_IDに 入れ
	_IDで チェック状態を取得し _状態に 入れ
	「状態=」を _メッセージに 入れ
	_状態を _バッファをつかい 文字列変換し _メッセージに 追加し
	_メッセージを ちょっと表示し
	0を 返し。

メインとは	(・ → ・)
		_レイアウトは		ID
		_チェックボックスは	ID
 (レイアウト)
	リニアレイアウトを生成し _レイアウトに 入れ
	垂直を			_レイアウトに 子の追加方向を設定し
	_レイアウトを レイアウトをアクティビティに追加し
 (チェックボックス)
	チェックボックスビューを生成し	_チェックボックスに 入れ
	20を				_チェックボックスに 文字のサイズを設定し
	「チェックボックスの例」を	_チェックボックスに 文字を設定し
	偽を				_チェックボックスに チェック状態を設定し
	_チェックボックスを		_レイアウトに ビューを追加し
	_チェックボックスを クリックリスナーを登録する
起動時の画面 チェックしたとき



 上記では、チェック状態が変化したタイミングでイベント処理させています。
 別の方法として、もし他にも各種設定のためのビューが存在していて、最後に「確定」ボタンをクリックするようなユーザインターフェースなのであれば、個々のチェック状態変化ぐらいでは情報を拾う必要はなく (「クリックリスナーを登録」も不要) 、確定ボタンのクリック時に1度だけ「チェック状態を取得」すれば良いでしょう。


アプリケーション終了時のイベント処理

■実行終り時の処理(仮/本定義)     
 プログラムの終了時、この処理単語が自動的に呼び出されます。(記述は任意です)
 他のイベント処理と異なり、戻値を返す必要はありません。(この先、さらにイベントを発生させることはないため)
文法
実行終り時の処理とは 本定義 (・ → ・)
記述例
作成中のデータを退避とは (・ → ・)
	〜略〜
	〜略〜。

実行終り時の処理とは 本定義  (・ → ・)
		作成中のデータを退避すること
		。


積極的なイベント発生

■意図的なイベント発生について
 端末を操作すると各種イベントが発生しますが、それとは別に、プログラムによって意図的にイベントを発生させることができます。
 イベント処理の最後では戻値を積む仕様となっていますが、その戻値の中に情報を埋め込む間接的な方法で後続イベントを発生させます。(イベントを発生させる処理単語が存在するわけではありません)

■「実行終り定数」を返す方法
 プログラムの実行を終わらせたい場合には、イベント処理の最後の戻値として「実行終り定数」という値を返してください。(注:標準Mindにある処理単語「実行終り」はAndroid版には有りません)
 「メイン」 もイベント処理の1つなので類似の方法をとりますが、メインには戻値が無いため、大域変数「メインの戻値」に情報を代入し、メイン自身のリターンは通常通りスタックを空にして戻ってください。
記述例
    (イベント処理内に記述する場合)

○○処理とは 本定義 (・ → 戻値)
	〜略〜
		ならば 実行終り定数を 返し
		さもなければ
			0を 返し
		つぎに。

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
    (メインの中で記述する場合)

メインとは (・ → ・)
	〜略〜
	エラー発生?
		ならば エラーメッセージを ちょっと表示し
			実行終り定数を メインの戻値に 入れ
			終り
		つぎに
	〜略〜。


■遅延実行をおこなう方法
 たとえば、2秒後に処理Aを実行したい場合、標準Mindでは
	二秒待ち Aする
のような書き方をしていましたが、Android版では副スレッドを使わないかぎり「n秒待つ」のような機能は使ってはいけません(処理単語は存在します)。
 その代わり、「遅延実行」と呼ぶ機構を使います(Android用語ではなくMind独自の呼び名です)。
 プログラムによるイベント発生はイベント処理の戻値にフラグを与えることで行いますが、本機能に限り、1〜65535の範囲の整数を積むことでおこないます。つまり、戻値の中に遅延したい値(ミリ秒単位)をそのまま入れます。
  • 遅延実行の目的で指定する値は1〜65535です(戻値の下位16bit)。そりよれ上位のビットが他のイベント発生のフラグに使われ、両者は共存できます。
  • 遅延時間は正確ではありません。指定した時間より短くなる傾向があるようです。
  • Android にはこれとは別のタイマー機能があるのですが今のMind for Androidの版では未サポートです。もう少しお待ちください。
文法
    (遅延実行処理を引き受ける単語の本定義)

遅延実行処理は 本定義 (・ → 戻値)
	〜
	<戻値>を 返す。

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
    (ペンディング中の遅延実行をキャンセルする)

遅延実行キャンセル → ・

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
    (遅延実行を発生させる)

  たとえば・・「ボタンクリック処理とは 本定義
    
(各種イベント処理)とは 本定義 (・ → ・)
    〜略〜
    <ミリ秒を表す数値>を 返す。
記述例
    (遅延実行処理を引き受けるための本定義)

遅延実行処理は 本定義 (・ → 戻値)
	「遅延実行が起動されました」を ちょっと表示し
	0を 返すこと。

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
    (遅延実行を発生させる例−イベント処理の中で)

ボタンクリック処理とは 本定義 (・ → 戻値)
	〜略〜
	2000ミリ秒を 返すこと。

−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
    (遅延実行を発生させる例−メインの中で)

メインとは	(・ → ・)
	〜略〜
	2000ミリ秒を メインの戻値に 入れること。
プログラム例
※ファイル名	Event/SpDelayExec.src

遅延実行ミリ秒は 数値 10000ミリ秒。

遅延実行処理は 本定義 (・ → 戻値)
	「10秒経過しました」を ちょっと表示し
	0を 返す。

ボタンクリック処理は	本定義  (ボタンID → 戻値)
		_番号は 変数
	IDから番号を得て _番号に 入れ
	_番号が 1に 等しい
		ならば 「開始しました」を ちょっと表示し
			遅延実行ミリ秒を 返し		※←タイマ開始
		さもなければ
			「キャンセルしました」を ちょっと表示し
			遅延実行キャンセルし		※←タイマ停止
			0を 返し
		つぎに。

メインとは
		_レイアウトは	ID
		_ボタン1は	ID
		_ボタン2は	ID
 (レイアウト)
	リニアレイアウトを生成し _レイアウトに 入れ
	〜略〜
 (ボタン1)
	ボタンビューを生成し _ボタン1に 入れ
	「10秒タイマー開始」を _ボタン1に 文字を設定し
	〜略〜
 (ボタン2)
	ボタンビューを生成し _ボタン2に 入れ
	「キャンセル」を _ボタン2に 文字を設定し
	〜略〜
	。



 なお、「遅延実行処理」の中でさらに遅延実行を要求することも可能です。結果的として永久に繰り返すインターバルタイマーとして働くことになります。その場合、ループを止める方法として2つの方法があります。
  1. 遅延実行の動作を止めるためのボタンを設置し、それが押されたらプログラム内部にフラグ (たとえば 「遅延実行中止要求は 変数。」 のような) を立て、遅延実行処理の中でそれを参照し もしフラグが立っていたら、さらなる遅延実行要求は出さず戻値として0を返すか、あるいはアプリを終了させたいなら「実行終り定数」を返す。
  2. 処理単語「遅延実行キャンセル」を呼び出す
 遅延実行がペンディングされている可能性のある場合にアプリを終了させたい場合は 「遅延実行キャンセル」 を呼び出してキャンセルしてください。あるいは、「実行終り時の処理とは 本定義 〜」 を定義し、実行終り時のタイミングでキャンセルする方法もあります。


■他のイベント発生機構(スレッド開始、シグナル要求など)
 準備中



Copyright(C) 2000 Scripts Lab. Inc.