| アプリケーションタイプ | 詳細 |
| MIDP | MIDPとCLDC仕様内のAPIのみを使ったもの。 |
| OEM-Specific | OEM-specific classも使ったもの。 |
| Native | Javaで書かれておらず、ネイティブシステムソフトウェア上。 |
レコードストア名はケースセンシティブでユニコードキャラクタ32文字。 レコードストア名はMIDlet suite内で唯一。 他のMIDlet suite内のMIDletレコードストアと同じ名前は良い。
このAPIではロック操作は与えられていない。レコードストアの実装は 個々のレコードストア操作はアトミック、同期、順序であり、 このため複数のアクセスで悪影響は起きない。 しかし、MIDletがレコードストアにアクセスする複数のスレッドを使っていたら、 アクセスをするのはMIDletの責任であり、予期しない結果が起きるかもしれない。 たとえば、あるMIDletでふたつのスレッドが両方ともRecordStore.setRecord()を同じレコードに対して同時に呼んだとき、レコードストアはこの呼び出しを適当に 順序化し、データベースに悪影響は出ない。 しかし、片方の書き込みがほかの書き込みを続けて上書きしてしまうため、 問題になるかもしれない。 同様に、あるプラットフォームでレコードストアの透過的な同期か、下からのアクセスが許されているとき、 MIDletsと同期エンジン間のレコードストアに対するアクセスを排他的にするのは プラットフォームの責任である。
レコードストアAPIはタイムスタンプにロング整数を使い、フォーマットは System.currentTimeMillis()。 レコードストアは最後に変更されたときのタイムスタンプを持つ。 またバージョンも持ち、レコードストアの内容を変更するたびにインクリメントされる 整数。 アプリケーションと同様に同期エンジンにも役立つ。
レコードは整数値recordIDで識別される。 レコードストアに最初に作られるレコードのrecordIDは1で、続きは1ずつ 増える。 MIDletsはRecordEnumerationクラスを使うことで他のインデクスを作る。
MIDlet suiteの要素は
ひとつ以上のMIDletsはひとつのJARファイルにパッケージされているかもしれない。 各MIDletはMIDletクラスと必要な他のクラスを拡張するクラスで成り立つ。 JARファイル内のマニフェストはMIDlet、名前、アイコンを実装する 各MIDletのクラスを指示する。 MIDletはアプリケーション管理ソフトウェアによって起動されるもの。 MIDlet suiteが呼ばれると、JVMはどのクラスか実行されるかが必要。 MIDletの新たなインスタンスはアプリケーション管理ソフトウェアに作成され、 MIDletを直接スタート、停止、破壊するのに使う。
MIDlets間でデータや他の情報を共有するのは個々のAPIと実装による。 例えば、あるMIDlet suiteに関連づけられたレコードストアをMIDlet間で共有する ときにつかうメソッドをレコード管理システムAPIは特定する。
MIDPはMIDP APIを実装するクラスを与える。 MIDPクラスはMIDPlet suiteクラスに取って代わられてはいけない。
ひとつのJARファイルは全てのMIDletのクラスを含む。 MIDletはJARファイル、MIDP、CLDC内のクラスのメソッドをロードし、呼び出す。 これら3つのスコープ内の全てのクラスはJARファイルのMIDletの実行時環境に 共有される。 これらのクラスを通じてアクセス可能なすべての状態は実行中のJavaクラスを利用可能 である。 すべてのMIDlets、MIDP、CLDCのオブジェクトを含むひとつの空間がある。 通常のJavaのロックと同期プリミティブは並行問題を避けるために必要なときに 使われる。 各ライブラリは並行をどのように扱うか、MIDletがマルチスレッド環境でどのように 安全に実行すべきかを特定する。
MIDletのクラスファイルは実行のみに利用可能で、リソースとしてや再利用のための 引用はできない。 CLDCの実装はJARファイルの内容を合った方法で保存、解釈できる。
JavaクラスファイルでないJARからのファイルは メソッドjava.lang.Class.getResourceAsStreamから利用可能である。 たとえば、マニフェストはこのように使う。
MIDletデスクリプタファイルの内容は、 javax.microedition.midlet.MIDlet.getAppPropertyメソッドで利用可能 である。
| 属性名 | 詳細 |
| MIDlet-Name | MIDletの名前 |
| MIDlet-Version | MIDletのバージョンナンバ。major.minor.micro |
| MIDlet-Vender | MIDlet suiteを与える組織 |
| MIDlet-Icon | JARファイル内のPNGファイル。アイコン |
| MIDlet-Description | MIDlet suiteの説明 |
| MIDlet-info-URL | MIDlet suiteの情報のあるURL |
| MIDlet-< n > | JARファイル内のn番目のMIDletの名前、
アイコン、クラスはコンマで区切られる。値nの最小値は1で連続した値をとる。
|
| MIDlet-Jar-URL | JARファイルのあるURL |
| MIDlet-Jar-Size | Jarファイルのバイト数 |
| MIDlet-Data-Size | MIDletに要求される不変データの最小バイト数。 デバイスはポリシーによって付加的なストレージを必要とするかもしれない。 デフォルトは0 |
| MicroEdition-Profile | 必要なJ2MEプロファイルで、システムプロパティmicroedition.profilesと同じフォーマットの値。例えば、MIDP-1.0。 |
| MicroEdition-Configuration | J2MEコンフィグレーション、システム プロパティmicroedition.configurationと同じフォーマットの値。 例えば、CLDC-1.0。 |
MIDlet-Versionタグがなければ、0.0.0と見なされ、非ゼロバージョンはより新しい バージョンと考えられる。
マニフェストは以下の属性を含まなければならない。
|
MIDlet-Name: CardGames MIDlet-Version: 1.1.9 MIDlet-Vender: CardsRUS MIDlet-1: Solitaire, /Solitare.png, com.cardsrus.org.Solitare MIDlet-2: JacksWild, /JacksWild.png, com.cardsrus.org.JacksWild MicroEdition-Profile: MIDP-1.0 MicroEdition-Configuration: CLDC-1.0 |
アプリケーション管理ソフトウェアにあるファイルがアプリケーションデスクリプタで あると認識指せるために、ファイルの拡張子とMIMEタイプが定義されている。
アプリケーションデスクリプタは以下の属性を含まなければならない。
一般的に、アプリケーションデスクリプタのフォーマットは属性名、コロン、属性値、 キャリッジリターン。 スペースは無視される。属性の順番は任意。
アプリケーションデスクリプタは転送や保存のためエンコードされるかもしれず、 パース前にユニコードにデコードされなければならない。 例えば、ISO8859-1エンコードファイルは適切なエンコードの java.io.InputStreamReaderと透過な方法で読まれる必要があるかも。 サポートされていれば、HTTPを使って扱われるデスクリプタは標準HTTP content negotiation mechanismが必要で、 ユニコードにデコードするためのコンテントエンコードヘッダや コンテントタイプパラメータのようなもの。
BNF for parsing Application Descriptors
|
appldesc: *attrline attrline: attrname ":" WSP attrvale wsp newline
attrname: 1*< any Unicode char except CTLs or separators >
newline: CR LF | LF
WSP: 1*( SP | HT ) separators = "(" | ")" | "<" | ">" | "@"
| "," | ";" | ":" | "'" | <">
| "/" | "[" | "]" | "?" | "="
| "{" | "}" | SP | HT
|
|
MIDlet-Name: CardGames MIDlet-Version: 1.1.9 MIDlet-Vender: CardsRUS MIDlet-Jar-URL: http://www.cardsrus.com/games/cardgames.jar MIDlet-Jar-Size: 7378 MIDlet-Data-Size: 256 |
MIDletがデバイスにインストールされるとき、クラス、リソースファイル、引数、 不変のストレージはデバイス上に保持される。 MIDletsはデバイスのアプリケーション管理ソフトウェアによってユーザに利用できる。
MIDletを実行するとき、MIDletのプライマリクラスのインスタンスが パブリックの無引数のコンストラクタを用いて作られ、 MIDletの状態に従ってMIDletのメソッドが呼ばれる。 MIDletは状態を変化させるか、アプリケーション管理ソフトウェアにMIDlet メソッドを用いて状態変化を知らせることができる。 MIDletが終わるか、アプリケーション管理ソフトウェアによって終了するとき、 破壊され、リソースは再利用できる、これには生成したオブジェクトやクラスが 含まれる。 MIDletはSystem.exitを呼び出してはならない、これはMIDletに呼ばれると SecurityExceptionを投げる。
Javaクラスの普通の状態はロードされたクラスによって影響をうけない。 どのクラスへの参照は状態をロードされるようにし、普通の静的な初期化が起る。
javax.microedition.midletパッケージのクラス
| クラス | 説明 |
| MIDlet | アプリケーション管理ソフトウェアがスタート、ストップ、破壊できるようにMIDletによって拡張されている。 |
| MIDletStateChangeException | アプリケーションが変化要求をできないときに投げられる。 |
ハイレベルAPIはビジネスアプリケーション用で、MID上で実行。 ポータビリティのため、ハイレベルAPIは高度な抽象化とルックアンドフィールの 制御。
ローレベルAPIは、ほとんど抽象化を行わない。 アプリケーションが正確な配置と要素の制御をローレベル入力イベントを行う。 特別な、デバイス特定の点にアクセスする必要もある。ゲームなど。
ローレベルAPIを使えば、アプリケーションは以下のことができる。
スクリーンの実装方法はデバイスごとで異なるため、アプリケーション側で 気をつければ、ポータビリティが保証される。単純なほうがうれしい。
3つのカテゴリ。
クラスDisplayは各実行中のMIDletのインスタンスで、 デバイスのディスプレイ能力の情報を扱うメソッドを与える ディスプレイマネージャとして動作する。 ScreenはDisplayのメソッドsetCurrent()を呼び出す ことで視覚化される。
Formは近い関係のUI要素を少し含むときに使われる。 これらの要素はItemのサブクラスで、ImageItem, StringItem, TextField, ChoiceGroup, Gaugeである。 クラスImageItem, StringItemはForm, Alertでのある種の操作を 実現する便利なクラス。 もし要素がスクリーンにすべて入らなければ、実装はフォームをスクロールできるよう にするか、新しいスクリーンをポップアップするか拡張できるようにしろ。
コマンドはクラスDisplayableのメソッドaddCommandとともに Displayable(Canvas or Screen)にインストールされる。
デバイスのネイティブなスタイルはある種のコマンドを標準的な場所に置くかもしれ ない。 Commandクラスはアプリケーションが意味的に実装と通信できるようにし、 これらの標準的な配置が効果をもちうる。
Commandオブジェクトは3つのコンストラクタパラメータを持つ。
void commandAction(Command c, Displayable d);ScreenかCanvasがCommandを付加しているか、 登録されたリスナがあればアプリケーションはこれらのイベントを得る。 リスナモデルのユニキャスト版は適合し、このためScreenかCanvas は一度にひとつのリスナを持てる。
Form内のItemの状態変化のためのリスナインターフェースが ある。インターフェースItemStateListener内に定義されているメソッド
void itemStateChanged(Item item);はGauge, ChoiceGroup, TextFieldの相互作用の値が変化するときに呼ばれる。それぞれの変化の後にリスナが呼ばれるとは予期されない。 しかし、もしアイテムの値が変化していたら、他のアイテムのために呼ばれる前か、 コマンドがフォームのコマンドリスナに届けられる前に、リスナは呼ばれる。 変化リスナは少なくともフォームフィールドから焦点がはずれた後に呼ばれるよう 提案される。 フィールドの値が実際に変化した後にリスナは呼ばれるべき。
public void keyPressed(int keyCode);keyRepeatedは全てのデバイスで利用できるわけではない。 アプリケーションはCanvasの以下のメソッドを呼ぶことでリピート操作が できるかどうかチェックできる。
public void keyReleased(int keyCode);
public void keyRepeated(int keyCode);
public static boolean hasRepeatEvents();APIは標準的なキーコードITU-I(0-9,*,#)を要求するが、キーパッドレイアウトは 要求しない。 実装は付加的なキーを与えるかも知れないが、これらのキーに依存する アプリケーションはポータブルではない。
さらに、クラスCanvasは抽象ゲームイベントを扱うメソッドを持つ。 実装は全てのキーイベントをデバイスのあうキーに割り当てる。 APIは抽象キーイベントのセットを定義する。UP,DOWN,LEFT,RIGHT,FIRE,GAME_A,GAME_B, GAME_C,GAME_D.
アプリケーション以下の呼び出しでは抽象キーイベントへのキーイベントのマップを 得る。
public static int getGameAction(int keyCode);アプリケーションのロジックがこのメソッドの返り値に基づくとき、 アプリケーションはキーパッドのデザインにかかわらずポータブルに実行できる。
抽象キーイベントのマップには以下も使える。
public static int getkeyCode(int gameAction);ここでgameActionは論理的なUP,DOWN,LEFT,RIGHT,FIREなど。 キーと抽象イベントのマップはゲームの実行中に変化しないと仮定する。
キー割り当ての例
ローレベルAPIはポインタイベントもサポートするが、全てのデバイスに以下の 入力機能があるわけではないので、以下のコールバックメソッドは デバイスによっては扱われない。
public void pointerPressed<(int x, int y);クラスCanvasの以下のメソッドでポインタが利用可能かどうかチェックできる。
public void pointerReleased(int x, int y);
public void pointerDragged(int x, int y);
public static boolean hasPointerrEvents();
public static boolean hasPointerMotionEvents();
Canvasとローレベルイベント機能が使われるとき、相互動作ができない デバイスもある。この場合は、実装はなにかのキーでコマンドモードにスイッチできる 方法を与えるかもしれない。 この場合、実行中のCanvasはメッセージshowNotify(), hideNotify()を受け取る。
ローレベルAPIでは、Canvasの再描画は非同期に行われるので 複数の再描画要求は最適化のためひとつの呼び出しで実装されるかもしれない。 これはクラスCanvasのメソッドrepaint()を呼ぶことで再描画要求 をする。 実際の描画はメソッドpaint()で行われる。これはCanvasの サブクラスで与えられる。そしてrepaint()と同期する必要はない。 これは後で起こるかも知れず、複数の再描画要求はひとつのpaint()呼び出し を起こすかも知れない。 アプリケーションは消去と再描画要求をserviceRepaints()で行える。
再描画の例。
24ビットカラーモデルは赤、緑、青にそれぞれ8ビットずつ与える。 すべてのデバイスが24ビットカラーをサポートしているわけではないので、 アプリケーションが要求する色をデバイスの表現できる色にマップする。 デバイスの特性を得るのにDisplayクラスを用い、これはどの色が利用可能で どれくらいの明確なグレイレベルが利用可能かを得る。 これでデバイス独立を妥協することなくアプリケーションがデバイスにあった 振る舞いが可能となる。
グラフィクスは直接スクリーンかオフスクリーンイメージバッファに描かれる。 これはグラフィクスオブジェクトの起源に基づく。 ディスプレイに描かれるオブジェクトはCanvasオブジェクトの paint()メソッドに渡される。 これはディスプレイに描かれるグラフィクスオブジェクトを得る唯一の方法。 さらに、アプリケーションはpaint()メソッドの持続時間の間だけ この方法を使うかもしれない。
オフスクリーンイメージバッファに描かれるグラフィクスオブジェクトは そのイメージのgetGraphics()メソッドを呼ぶことで得られる。 これらのオブジェクトはアプリケーションに無限に保持されるかもしれず、 これらのオブジェクトに対する要求はいつでも起こりうる。
クラスGraphicsはsetBackgroundとsetForeground呼び出しのかわりに 色のセットのためメソッドsetColor()のみを持つ。 これは描画エリアの後ろは明示的なfillRect()呼び出しで描かれなければ ならないから。
座標システムはピクセル間の位置を表し、ピクセル自身ではない。 このため、ディスプレイの左上の最初のピクセルは座標(0,0)(1,0)(0,1)(1,1)の 間にある。
アプリケーションはCanvasの以下のメソッドで利用可能な描画エリアを 尋ねる。
public static final int getWidth();
public static final int getHeight();
システム内の各フォントは個々に実装されている。 新しいFontオブジェクトのインスタンスを作るかわりにスタティックな getFont()メソッドを呼ぶ。 これはフォントに使い方に関係するごみの生成を除去する。
Fontクラスはフォントにアクセスする呼び出しを与える。 以下の属性はFontクラスからのフォント要求に使われる。
テキストを描画するメソッド
public void drawString(String text, int x, int y, int anchor);テキストは現在のフォアグラウンドとバックグラウンドの色で、 現在のフォントでアンカーポイント(x, y)に描かれる。 アンカーポイントの定義はローカルに垂直定数(TOP,BOTTOM)と結合された 水平定数(LEFT,HCENTER,RIGHT)のどれか。 垂直方向のセンタリングはAPIには定義されていない。 テキストの例。
UI APIは他のUIツールキットに似たイベントの同期のための機能を持つ。 クラスDisplayのメソッドcallSerially()で、 アプリケーションはイベントの操作を連続して行う。 CallSerially()はsericeRepaints()と同じ効果を持つ。
CallSerially()とsericeRepaints()の例。
UI要素のいくつかの実装、スクリーンやアイテム、はネイティブ要素に基づく。 Javaオブジェクトがこれ以上必要ないとき使用中のリソースは解放されるのは 実装による。 ひとつとしてはKVMのコレクタのフックである。
MIDlet管理ソフトウェアの機能を述べるため、MIDletsの異なるクラスを定義する。
| クラス | 説明 |
| Permanent | 少なくとも一部は、不揮発性のメモリに置かれる。 多くの機能を取り扱う。何度もダウンロードせずに繰り返し実行。 |
| System | 少なくとも一部は、不揮発性のメモリに置かれる。 小さいか、大きい。 デバイス特定の機能を実現する。 |
Systemクラスは、Permanentクラスの特別な場合。 MIDの製造者に作成され、デバイス特定の機能を実現。 デバイスの非公開な機能にアクセス。 すなわち、ある意味で、他のMIDletクラスよりも特別な状態で操作する。 システムクラスMIDletは検索やインストールで特別な制約があるかもしれない。
MIDは本節で述べたMIDletのクラスをサポートするかどうかわからない。 ターゲットデバイスの限界を認める以外、開発者はMIDletクラスの区別をする必要は ない。
MID管理ソフトウェアが行えなければならない操作がある。
| 操作 | 説明 |
| Retrieval | MIDletをソースから取ってくる。メディア認証、交渉、検索。 |
| Installation | MIDにMIDletをインストール。検証、変更。 |
| Launching | MIdletの呼び出し。点検、呼び出し。 |
| Version Manegament | MIdletを新しいバージョンにアップグレード。点検、バージョン管理。 |
| Removal | 以前にインストールしたMIDletの削除。点検、削除。 |
MIDPの実装は、MIDletがMIDのセキュリティポリシーを犯さないかを検証する必要が ある。たとえば、MIDletが信頼できるソースから持ってこられたかどうかを 「コードサイン」機能で確認する。 次にMIDletを一般的な形からデバイス特定の内部表現に変形。 この変形は永続的なストレージに書き込むのと同じくらい単純で、 実際にMIDletを不揮発性メモリから直接実行できるようにする。
インストール後、MIDletは起動可能。これは点検ステップを行う。 MIDletを選択、呼び出す。 呼び出しはMIDletをKVMに入れる。この時点で、8章「アプリケーション」で述べた APIがMIDletの制御に使われる。
インストール後のある時点で、新しいバージョンのMIDletが利用可能になる。 アップグレードするために、MIDlet管理ソフトウェアはなんのMIDletがインストール されているかを追跡し(認証)、バージョンナンバをチェックする(バージョン管理)。 この情報を用いて、古いバージョンのMIDletをアップグレードする。
削除。これは前の点検後のステップと少し異なり、MIDlet管理ソフトウェアは インストールされたMIDletのイメージと関係のあるリソースを削除する。 これは7節「永続的なストレージ」に述べたAPIを用いて作られたレコード も含む。
アプリケーション管理ソフトウェアはMIDletのインストールやアップグレードを アプリケーションデスクリプタと一致するJARファイルによる。
MIDlet suiteをアプリケーションデスクリプタかJARファイルでインストール したいとき、アプリケーション管理ソフトウェアは現在インストールされている MIDletのひとつかどうかチェックする。 JARファイルはマニフェストのMIDlet名とMIDletベンダ属性によって唯一とされる。 これらの値がマッチしたら、同じということになる。 この場合はMIDletバージョンが新しければ、ダウンロード、インストールの前に ユーザに確認する。
MIDlet suiteの更新がなんらかの理由で失敗したら、古いバージョンがそのまま 残ることを確認すべき。 更新が成功したら、古いバージョンは削除される。 更新プロセスの一部として、MIDlet suiteのストレージは更新されるアプリケーション が使うために保護される。
MIDlet suiteが削除されるとき、全ての要素、ストレージ、リソースは デバイスから削除されるべき。
MIDP実装はRMSパーマネントストレージ(?)内でデータフォーマットの更新に 責任はない。 更新されたMIDletが異なるデータフォーマットを持っている場合、 データの更新はMIDletの責任。