第 1 回 : 携帯 Java と IM
はじめに
本連載では、モバイル・インスタントメッセンジャーを例に挙げて、携帯 Java ( J2ME/MIDP ) プログラミングに関して開発者が陥りがちなポイントを Tips 集としてまとめます。
- 第 1 回 : 携帯 Java と IM
- 第 2 回 : 仕様・設計と実装( IM "improve" の機能仕様と J2ME/MIDP のつまずきどころ)
- 第 3 回 : 仕様・設計と実装( IM "improve" の設計・実装とエミュレーター動作)
- 第 4 回 : IM "improve" を実機に載せよう( IM "improve" のダウンサイズ)
- 第 5 回 : インターフェイス構築のヒント
- 第 6 回 : IM "improve" の実機対応と携帯電話の将来展望
本連載について
携帯 Java 特有の制約事項を着眼点において話を進めます。
第 1 回
IM の仕様と設計に関する、大まかなポイントを紹介します。
第 2 〜 3 回 仕様・設計と実装
IM の仕様を決め、具体的に携帯 Java にあわせて設計、実装します。
第 4 〜 5 回 実機に載せよう(ダウンサイズとユーザーインターフェイス)
SophiaCompress(Java)、サイズ圧縮とユーザーインターフェイスのテクニックを紹介します。
第6回 実機対応と携帯電話の将来展望
実際に IM を実機で動かします。それから携帯電話の将来について展望します。
前提条件
Java 言語でのプログラミング経験
IM の紹介
IM とは、相手のステータス(状態)を電話をかける人が予め確認できるツールです。IM が出現するまでは、「予め相手の状態を確認する」概念はありませんでした。
2000年 以降、IM は、インターネットのブロードバンド化と共に急激に普及しています。
IM の機能
IM の基本機能は、友達管理、状態確認、コミュニケーションの 3 つです。
友達管理機能
友達の追加や削除、グループ化などの機能です。
状態確認機能
友達のプレゼンスやステータスを取得する機能です。
コミュニケーション機能
コミュニケーションの手段で、同期と非同期の 2 種類があります。
UI(ユーザーインタフェース)について
PC 上の IM ではトップ画面に友達のリストが表示され、友達の状態をいつでも見れます。携帯電話でも同じような UI が使いやすいでしょう。
それでは、テキストベース IM の UI の例を示します。
テキスト型 UI
アイコンベース IM の UI の例です。
アイコン型 UI
1 人の友達をトップ画面に配置した常駐型 IM の UI の例です。
常駐型 UI
サイズ制限を乗り越えて…
NTT DoCoMo、KDDI、J-PHONE それぞれが独自に携帯 Java の仕様を拡張し、サイズ制限を設けています。
キャリア | サイズ(KB) | |
---|---|---|
DoCoMo | 503 | 10 |
504 | 30 | |
J-PHONE | 旧 | 30 |
新 | 80 | |
au | 50 |
i アプリが登場した当時は 10 Kバイト制限の中でアプリを実装する必要がありました。サイズ制限は緩和される方向にありますが、サイズ制限は常に意識しなければならない状況に変わりはありません。
携帯 Java アプリ開発では、Java のオブジェクト指向の特長を活かしにくいかもしれません。2 のクラスだけで開発しなければいけない状況も珍しくありまあせん。
サイズ削減の方法として次の 3 つを挙げることができます。
- アルゴリズムを変える方法
- データ領域を小さくする方法
- JAR 圧縮ツールを利用する方法
簡単に表にすると次のようになります。
アルゴリズム | データ領域最小化 | JAR ツール |
---|---|---|
省サイズ設計 アルゴリズム最適化 … |
クラス融合 未使用項目の削除 名前の短縮 名前の共有 … |
7-ZIP KZIP … |
携帯 Java 圧縮ツール : SophiaCompress(Java)
DoJa と MIDP の GUI
携帯電話は画面が小さい上に、使えるコンポーネントも限られます。
DoJa と MIDP は同じ携帯 Java でありながら、GUI に関しては設計思想が大きく異なります。それぞれのプロファイルの GUI 関連クラス図です。
機能 | DoJa | MIDP1.0 | 相違点 |
---|---|---|---|
GUI トップ | Frame | Displayable | 設計思想の違いから MIDP では切り替えられる回数が多くなります。 |
低水準描画 | Canvas | Canvas | 特に大きな違いはありません。両者ともにポインティングデバイスにも対応しています。(DoJa では2.0から) |
ダイアログ | Dialog | Alert | Dialog では3つの選択肢が出せますが、Alert では CommandListener が登録できないため、分岐には使えません。なお、Alert ではタイムアウトが設定できます。 |
コンポーネントコンテナ | Panel | Form | MIDP のレイアウト関連は貧弱です。 |
GUIコンポーネント | Component | Item | Component では座標指定で配置できますが、Itemでは追加順序しかありません。 |
文字表示 | Label | StringItem | StringItem ではラベルと内容の2つの部分に分かれています。 |
画像表示 | ImageLabel | ImageItem | ImageItem では String のラベルが付けられます。 |
ボタン | Button | なし | MIDP では、ボタンは使用できません。このため Choice や List を使うことを除けば、1画面からユーザーの選択によって分岐できるフローの数はソフトキーの個数と同じになります。 |
テキスト入力 | TextBox | TextField, TextBox | DoJa では縦横幅が自由ですが、MIDP では、1行または1画面のいずれかとなります。 |
選択肢 | ListBox | ChoiceGroup, List | DoJa では選択肢表示の UI が選べますが、MIDP では選べず実装依存です。 |
日付入力 | なし | DateField | MIDP では日付選択専用の入力コンポーネントがあり、カレンダーを表示して選択させる高度な実装も存在します。 |
量調節バー | なし | Gauge | MIDP では量調節用コンポーネントが提供されています。 |
DoJa でも MIDP でも低水準 API の Canvas では自由に線や文字・画像を描画することが可能で、使い勝手には大差はありません。
大きな相違点は高水準 API にあります。コンポーネントコンテナとして DoJa では Panel、MIDP では Form が提供されていて各コンポーネントの配置は、DoJa では PC と同じようにウィンドウに貼り付ける感覚で細かく指定できますが、MIDP では細かな指定はできません。
DoJa と MIDP の違いは「ボタンコンポーネント」で顕著です。DoJa では任意の機能を持たせたボタンを好きな場所に貼れますが、 MIDP では「ボタンコンポーネント」そのものがありません。
DoJa では Panel を使ってあっさりと GUI 画面を構成できますが、MIDP では 1 つの Form だけでは作れません。複数の画面が必要になります。
MIDP では以下の点に留意してください。
- 1 つの画面に多くの機能を載せない
- 複雑な処理が必要になるメイン画面では Canvas を使う
- 細かに画面を切り替える
なお、DoJa でも、使いやすい GUI にしたい場合は、文字入力など必要な部分のみ高水準 API を使い、それ以外は低水準 API を使用するスタイルになります。
このアプローチのメリットは、DoJa ⇔ MIDP 間でも移植が容易な点です。
※ MIDP 2.0 ではレイアウト機能が強化されています。
簡単な通信アプリの作成
現在の携帯 Java では通信は基本的に HTTP (または HTTPS )に限られています。
「端末→サーバー」の通信は任意のタイミングで行えますが、「サーバー→端末」の通信はできません。
IM では、状態が変わった時やメッセージが届いた時にサーバーからクライアントへ通信した方が良い場合もありますが、HTTP では不可能です。
クライアントが定期的にサーバーに問い合わせる必要があります。この通信方式は「ポーリング」と呼ばれます。
サンプルプログラム「DBTest」の概要
- 名前と状態はユーザーが制限字数内で自由に入力できます。
- 「設定」ボタンを押すと、名前と状態を送り、それをデーターベースに登録します。
- 「取得」ボタンを押すと、データーベースから名前と状態の組一覧を取得し表示します。
システムの構成図です。
クライアントとサーブレットは HTTP で通信します。サーブレットはクライアントからのリクエストに応じ JDBC 経由でデーターベースを操作します。
このプログラムではクライアントは別のクライアントが情報を更新したことを知るすべがありません。このため、定期的に手動で「取得」を行わないと情報が古いままとなってしまいます。
なお、サンプルをコンパイル・実行する環境については「エキストラトラック!」をご覧ください。
クライアントの詳細
KDDI、J-PHONE のどちらの端末でも動作させられるように MIDP の API のみで作成しました。
ただし今回は実機へ搭載させるところまで行わず、Sun の MIDP エミュレーターで動かすにとどめます。実機で動かしたい場合は、公式情報源の参考サイト 2、3 のほか、参考書籍 13 に詳しい説明があります。
以下はサンプルの詳細についての解説です。
クライアントには 2 つのクラスがあります。
DBTestMIDlet クラス( DBTestMIDlet.java )
MIDlet を継承したアプリのメインクラスです。実装義務がある3つのメソッドが記述してあります。最初の表示処理以外、何もしていません。
- 15行 startApp メソッド
- アプリのメイン画面である DBTestForm のインスタンスを作成し、表示しています。
- 23行 pauseApp メソッド
- 29行 destroyApp メソッド
- 空のメソッドです。
DBTestForm クラス( DBTestForm.java )
Form を継承したアプリのメイン画面です。コマンド(ソフトキー)を処理するため CommandListener をインプリメントしています。
28行 定数 URL
サーブレットへのアクセスに用いるURLの基本部分です。 http://(tomcatの動いているサーバー):(ポート)/(サーブレットの場所)/(サーブレットの名前) となっています。
33行 コンストラクタ
準備と画面の作成を行います。
35〜42行
コマンドの作成、登録とリスナーの登録を行っています。
44〜52行
名前と状態入力用の TextField と状態リスト表示用の StringItem を作成し、追加しています。なお TextField の入力は6文字までとしました。
61行 encode メソッド
文字列を URL エンコードします。サーブレットとのやりとりで HTTP を使用するので、パラメーターの文字列は URL エンコードして送信する必要があります。詳しくは述べませんが、J2SE ではこの機能を提供する java.net.URLEncode クラスが存在していますのでそちらを参照して下さい。なお KDDI-P では com.jblend.HttpUrlEncoder というクラスが利用可能です。
97行 commandAction メソッド
キーが押された時の処理を行います。
101〜126行
「設定」キーが押された時の処理です。nameField、stateField から内容を取得し、それらをパラメーターとした URL を作成し、HTTP の GET メソッドで通信しています。URL は、 (上記の基本部分)/set?name=(名前)&state=(状態) となっています。encode メソッドで名前と状態を URL エンコードしています。今回のサンプルではクライアントがサーブレットに要求するパス(/set または /get)でサーブレット側に設定か取得かを判断させることにしました。なお、一般的には URL で要求するドキュメント等を指定した後、クライアントとサーブレット間でデーターのやりとりを行うのですが、このサンプルでは設定時の HTTP リクエストにクライアントが送りたい情報を乗せてしまいましたので、111行で開いた InputStream ではやり取りをせず、そのまま閉じているだけです。
127〜154行
「取得」キーが押された時の処理です。URLを(上記の基本部分)/get として HTTP の GET メソッドで通信しています。MIME タイプの application/octet-stream を用いてバイト列を受信しますので、http.getLength()でバイト長を読んだ後、byte 型の配列(data)に読み込んでいます。その後、String として認識させています。リソースの後始末が続き、154行で取得した情報を state に設定し、表示を更新させています。
サーブレットの詳細
データベースについて
今回のサンプルでは DBTestServlet はデータベースエンジン上の dbtest というデータベースに users というテーブルが存在していることを前提に動作します。テーブルの構造は
users name varchar(12) state varchar(12) となっています。テーブルの作成等については「エキストラトラック!」を参照してください。なお、クライアント側では6文字までに入力を制限しましたが、2バイト文字の扱いがデータベースエンジンやバージョンによって異なるため安全をみて12文字としてあります。
DBTestServlet (DBTestServlet.java)
サーブレットで使用するのはこのクラスのみです。HttpServlet を継承しています。
12〜16行
データベースへの接続に必要となるユーザー名とパスワードの定数が定義してあります。作成してある dbtest データベースにこのアカウントでアクセスできる必要があります。
18〜24行、26〜31行
MySQL、PostgreSQL についてそれぞれ JDBC ドライバ名とデータベース接続先の定数が定義してあります。プログラム自体は MySQL を使用するようになっていますが、93、124行の"MYSQL_DRIVER"を"POSTGRESQL_DRIVER"に、94、125行の"MYSQL _CONNECTION"を"POSTGRESQL_CONNECTION"に書き換えることで、PostgreSQL を使用できるようになります。
36行 doGet メソッド
このサーブレットのメイン部分です。クライアントから HTTP の GET メソッドでリクエストを受けるとこのメソッドが tomcat から呼ばれます。
まず39行でサーブレットにリクエストされたパスを取得します。今回のサンプルでは"/set" か "/get"のいずれかになります。
44〜58行 パスが"/set"の場合(「設定」の場合)
まず、HTTP リクエストのパラメーターから名前(name)と状態(state)を取得します。正常に取得できれば、putToDatabase を呼び出します。正常だった場合0、異常だった場合-1をクライアントに返送するようにbufにデータを入れています。(クライアントでは実際にこの返り値は確認していません。)
59〜63行 パスが"/get"の場合(「取得」の場合)
getFromDatabase を呼び、その返値をバイト列にして buf に代入しています。
64〜73行 その他の場合
今回のサンプルではクライアントの DBTest から上記の2つの場合に当てはまらないリクエストがくることはありません。しかし、サーブレットはその他のリクエストを受けることもあり得ますので、その場合の処理を行っています。具体的には getFromDatabase で取得した文字列をテキスト形式で出力しています。これは通常の Web ブラウザでクライアントの部分で述べた「 URL の基本部分」にアクセスすれば確認することができます。
75〜80行 クライアントへの返信
buf に格納されているバイト列を MIME タイプの"application/octet-strem"で送ります。
90行 putToDatabase メソッド
データベースに名前と状態の組を登録します。
93行
JDBC ドライバをロードします。
94行
データベースとの接続を確立します。
98〜99行
すでに users テーブルに同一の名前で状態が登録されている可能性がありますので、それを削除します。具体的には SQL 文で「delete from users where name='名前'」を実行することになります。結果集合(ResultSet)は返りませんので、Statement の executeUpdate メソッドを用います。
102〜104行
users テーブルに名前と状態の組を登録します。SQL 文で「insert into users (name, state) values ('名前','状態')」を実行します。こちらも executeUpdate を使用します。
120行 getFromDatabase メソッド
データベースから名前と状態の組の一覧を取得して、文字列として返します。
124行
JDBC ドライバをロードします。
125行
データベースとの接続を確立します。
131行
SQL 文「selct * from users」を実行して users テーブルから全てのデータを取得します。今度は結果集合( ResultSet )が返りますので、executeQuery を使用します。
132〜136行
結果集合の各行にアクセスして、「名前 : 状態」の組を改行で区切ってresult に格納していきます。各列は添え字1からはじまりますので、注意が必要です。
まとめ
サンプルプログラムを動かすことはできましたでしょうか?
クライアント1つでは面白くも何ともありませんが、離れた場所で複数起動してみると、IM によって実現される世界の片鱗が見えて楽しいかもしれません。
エキストラ トラック!
サンプルプログラムをコンパイル・実行するための環境
サンプルプログラムを動かすための環境について説明します。Windows 2000/XP 環境を前提にします。
参考サイト・書籍
1. The Source for Java Technology
Sun の Java 公式サイトです。
2. 技術情報
ezplus の技術情報です。
3. J-PHONE Developer Program 技術情報
J-PHONE Java の技術情報です。
-
DoCoMo Java の技術情報です。
5. 7-ZIP
高圧縮 ZIP 圧縮ツールです。
-
Java で様々な開発を行っているオープンソースプロジェクトです。TOMCAT がダウンロードできます。
-
The Apache Jakarta Project の日本のコミュニティです。
8. MySQL: The World's Most Popular Open Source Database
MySQL の開発元のサイトです。
-
MySQL の日本のコミュニティです。
10. PostgreSQL
PostgreSQL の開発元のサイトです。
-
PostgreSQL の日本のコミュニティです。
12. Cygwin
Red Hat が開発を行っている Cygwin のサイトです。
13. 書籍「Java2ME MIDP ゲームクリエーターズガイド」技術評論社 ISBN4-7741-1470-7
MIDP での開発について詳しく解説されています。
14. 書籍「エキスパートから学ぶ PostgreSQL 活用テクニック」インプレス ISBN4-8443-1628-17
データーベースの基本から書いてあります。Cygwin 版 PostgreSQL についても詳しく解説されています。