メンバページ: (小)

iアプリの作り方


このページでは、iアプリを作成する方法を一から解説していこうと思います。尚、端末は505i, 506iシリーズを対象とします。Javaの知識があることも前提に書いていこうと思います。あしからずm(_ _)m


- 更新記録 -
1日目 まずは開発環境の整備から
2日目 HelloWorld for iアプリを作ってみよう
3日目 iアプリ開発ツールを使ってみる
4日目 DoJaプラグイン for Eclipseを使ってみる
5日目 実機で動かしてみる
6日目 サーバとHTTPで通信してみる
7日目 圧縮ツールを使ってみる
8日目 ブロック崩しを作ってみる(Part1 - 描画処理編)
9日目 ブロック崩しを作ってみる(Part2 - アニメーション編)
10日目 ブロック崩しを作ってみる(Part3 - イベント処理編)

1日目 --- まずは開発環境の整備から

iアプリの実行環境

ご存知のとおり、iアプリはNTTドコモの携帯電話で利用できるアプリケーションのことで、Java実行環境上で動作します。ただし、J2SE上で動作するわけではなく、J2MEのCLDC(Connected Limited Device Configuration)というコンフィグレーション上で動作します。

J2MEには対象とするハードウェアの性能に合わせて2つの実行環境を選択できるように設計されています。一つがCDC(Connected Limited Device)で、こちらは比較的ハードウェアの制約を受けないプラットフォームを対象としたものです(大型PDA、カーナビ等)。もう一方はハードウェアの制約が大きい小型の端末を対象としたもので、携帯電話がその代表格といえるでしょう。DoCoMoの携帯電話だけでなく、J-PhoneやKDDIの携帯電話に搭載されているコンフィグレーションもCLDCです。

更にコンフィグレーションの上には「プロファイル」というクラスライブラリを積み上げることができます。代表的なプロファイルは、DoCoMoが自社の携帯電話に搭載するために開発した「DoJa」や、vodafoneのVアプリやauのEZアプリで利用されているMIDPがあります。

iアプリ開発に必要なものは?

それではiアプリの開発には何が必要なのでしょうか?ここではPCでの動作確認も含め、「開発」に必要なものを挙げてみました。

開発者ガイドには、J2SEのバージョンが1.3.1とありますが、恐らく1.3.1以降であれば問題ないと思われます(筆者はJ2SE1.4で動作確認しています)。

エディタは特に指定はありませんが、筆者はEclipseが便利だと思います。というのも、iアプリ作成ツールにEclipse向けプラグインが付属しており、iアプリの動作に必要な手順をこのプラグインが行ってくれるからです(もちろんEclipseを使わなくても難しいものではありませんが・・)。次回から紹介する例ではEclipseを使うことを前提に進めていこうと思います。

インストール

まずはJ2SEをインストールしましょう。J2SEの媒体はSUNのサイトからダウンロードできます。執筆時点の最新版は1.4.2_04です(インストール手順は省略します)。

エディタにEclipseを使う場合はEclipseもインストールしておきます。Eclipseのサイトから媒体をダウンロードしましょう。最新の安定版は2.1.3です。3.xはiアプリ作成ツールに含まれるプラグインが対応していない可能性があるので、注意が必要です。

次にiアプリ作成ツールのインストールを行います。まずはDoCoMoのサイトから媒体をダウンロードしましょう。ここからダウンロードできます。ダウンロードしたファイルを展開し、その中のDISK1/setup.exeを実行します。表示される画面の指示に従っていくと、以下の画面が出てきます。

エディタにEclipseを使わない場合は「標準」を選択してください。Eclipseを使う場合は、「カスタム」を選択します。「カスタム」し、「次へ」を押下すると、以下の画面が表示されます。

ここで、「Sun(TM) ONE Studio 4, CEモジュール」のチェックを外し、「次へ」を選択します。

すると、eclipseのインストールフォルダを指定する画面が表示されます。正しいパスを設定し、「次へ」を押下します。後は画面の指示に従うことでインストールは完了です。

これでiアプリを開発するための最低限の環境が整いました。次回はお決まりのHelloWorldを作成する方法を紹介しようと思います。PC上でのエミュレータの実行についても紹介します。

このページトップへ

2日目 --- iアプリで作るHelloWorld

iアプリ作成の手順

iアプリの作成手順は以下のようになります。

  1. ソースコードの作成
  2. コンパイル
  3. クラスファイルの事前検証
  4. Jarパッケージの作成
  5. ADF(Application Descriptor File)の作成
  6. エミュレータによる動作確認
  7. Webサーバへの配置
  8. 携帯電話からWebサーバへアクセスし、iアプリをダウンロード&実行

長くなりそうですので、今回は1〜6までの流れをざっと見ていこうと思います。7以降は次回以降で紹介しようと思います。また、必要な作業を理解するために、敢えてIDEは使わずに一つ一つ実行していきます。

1. ソースコードの作成

以下は画面に"Hello World!"と表示する非常にシンプルなプログラムのソースコードです。

package hello;

import com.nttdocomo.ui.*; // (a)

public class HelloWorld extends IApplication { // (b)
    public void start() { // (c)
        Display.setCurrent(new HelloPanel()); // (d)
    }
    
    class HelloPanel extends Panel { // (e)
        public HelloPanel() {
            add(new Label("Hello World!")); // (f)
        }
    }
}
(a)com.nttdocomo.uiパッケージのインポート
このパッケージはアプリケーションやユーザインタフェースの作成に必要なクラスが収められています。iアプリを作成する上で必ずimportする必要があるパッケージです。
(b)IApplicationクラスの継承
すべてのアプリケーションは、このIApplicationクラスを継承する必要があります。アプレットがjava.applet.Appletを継承する必要があることと似ていますね。
(c)start()メソッドの実装
アプレットと同じように、iアプリはmain()から実行されるアプリケーションではありません。そのため、アプリケーションのスタートポイントが必要で、それがこのstart()メソッドになります。アプリケーション起動時に行うべき処理をここに記述します。
(d)Display#setCurrent()の呼び出し
このメソッドは表示するフレームの設定を行います。この例ではPanelクラスを継承したHelloPanelクラスのオブジェクトを設定しています。尚、awtのPanelとは異なり、com.nttdocomo.uiパッケージのPanelクラスはFrameを継承しているので、setCurrentの引数に与えることができます。
(e)Panelクラスの継承
コンポーネントを配置する「コンテナ」としてPanelクラスを継承したHelloPanelクラスを定義しています。com.nttdocomo.uiパッケージでは、Panel以外にCanvasクラス(描画を行うためのフレーム)とDialogクラス(ユーザに確認を求めるフレーム)があります。
(f)Labelの追加
"Hello World!"という名前のラベルを貼り付けています。この方法はawtとまったく同じですね。

ソースを見ると、アプレットと良く似ています。アプレットはブラウザからWebサーバへアクセスし、クラスファイルをダウンロードしてブラウザ上でJavaプログラムを動作させる仕組みでした。iアプリはどうかと言うと、ブラウザの代わりに携帯電話が実行するようになるだけで、後は基本的には流れは同じです。そのため、アプレットを作ったことがある人にとっては入りやすいのではないでしょうか。

2. コンパイル

コンパイルでは、既にインストールした「DoJa-3.0プロファイル向けiアプリ作成ツール」に含まれるCLDCのクラスファイル(classes.zip)と、DoJa3.0のクラスファイル(doja_classes.zip)をクラスパスに含める必要があります。デフォルトでは、C:/iDKDoJa3.0/lib 以下に置かれているので、それを追加してください。

> javac -target 1.1 -classpath %DOJA_HOME%/lib/classes.zip;%DOJA_HOME/lib/doja_classes.zip HelloWorld.java

ひとつ注意が必要なことは、J2SE1.4環境では -target 1.1 オプションを追加して、JDK1.1と互換性があるクラスファイルを生成させる必要があることです。CLDCは1.1と互換性のあるクラスファイルが必要のようで、コンパイル自体はこのオプションを付けなくても通るのですが、次のクラスファイルの事前検証でひっかかります。J2SE1.3では、デフォルトで1.1と互換性のあるクラスファイルが生成されるので問題ありませんが、J2SE1.4ではデフォルトで1.1と互換性のないクラスファイルが生成されます。そのため、このオプションが必須になるので、気をつけてください。後に紹介するEclipseを使ってビルドする場合も同様の注意が必要です。

(注)DOJA_HOMEは各自の環境に合わせてください

3. クラスファイルの事前検証

iアプリでは、クラスファイル生成後、クラスファイルの事前検証を行う必要があります。J2SEでもJavaVMがクラスファイルの検証を実行前に行っています。ただし、その検証には負荷がかかります。携帯電話というリソースの少ないプラットフォームでなるべく負荷を少なく動作させるために、検証できる部分を予め行っておくという考えで、このような手順が必要になっています。J2SEのクラスファイルの検証が2ステップに分かれるというイメージですね。

この事前検証には「DoJa-3.0プロファイル向けiアプリ作成ツール」に含まれる preverify.exe を使用して以下のように行います。

> %DOJA_HOME%/bin/preverify.exe -cldc -d classes
 -classpath classes;%DOJA_HOME/lib/lib/classes.zip;%DOJA_HOME/lib/doja_classes.zip
 hello.HelloWorld hello.HelloWorld$HelloPanel

"-d classes"で検証済みクラスファイルの出力先を指定します。"-classpath"オプションではコンパイル時と同じように2つのzipファイルと、コンパイルで生成されたクラスファイルの格納場所を指定します。最後に事前検証を行うクラスを完全修飾クラス名で指定します。

4. Jarパッケージの作成

DoJaではダウンロードされるクラスファイルは一つのJarにまとめる必要があります。そのため、生成されたクラスファイルをJarコマンドで一つのアーカイブにします。

> jar cvf hello.jar classes/hello/*.class

5. ADF(Application Descriptor File)の作成

携帯電話がiアプリをダウンロードする際、最初にダウンロードされるのはADFと呼ばれるアプリケーションの情報を記述したファイルです。携帯電話のJAM(Java Application manager)がこのファイルをダウンロードし、Jarのダウンロード,インストール,起動等を行っています。

ADFにはJAMがアプリケーションを実行するための情報として、最低限以下を記述しておく必要があります。

以下はHelloWorldアプリケーションのADFの例です(ファイル名はhello.jam)

AppName = HelloWorld
AppClass = hello.HelloWorld
PackageURL = hello.jar
AppSize = 1440
LastModified = Tue, 22 July 2004 09:52:46

PackageURLはアプリケーション(Jarファイル)のURLを指定します。相対パスを記述した場合は、JAMファイルからの相対パスになります。AppSizeはJarファイルのサイズ,LastModifiedは最終更新日です。これらを手で入力するのは面倒なので、できればツールにまかせたいところです。次回以降ではこのADFを自動生成する方法を紹介する予定です。

6. エミュレータによる動作確認

実機で動作させる前に、まずはエミュレータで動作を確認してみましょう。エミュレータのexeは、%DOJA_HOME%/bin 以下のdoja.exeとdoja_g.exeの2つあります。後者はデバッグ情報が必要な場合に実行します。開発時にはこちらを実行したほうが良いでしょう。

> %DOJA_HOME%/bin/doja_g.exe -i hello.jam

以下のような画面が表示されればエミュレータでの実行は成功です。


今回はIDEを使わなかったため、コンパイルや事前検証,JAMファイルの作成が面倒でした。次回以降では、iアプリ作成ツールを使った開発方法と、Eclipseを使った開発方法を紹介しようと思います。また、今回示さなかった、Webサーバへのアプリケーション配置方法や、実機での実行についても紹介していこうと思います。

このページトップへ

3日目 --- iアプリ開発ツールを使ってみる

今回は「DoJa-3.0プロファイル向けiアプリ作成ツール」(以下、iαppliTool)を使ってビルドから動作確認までを行ってみようと思います。ビルド対象は2日目と同じものを使います。

ツールの起動

まずはツールの起動です。前回もエミュレータの起動に使いましたが、%DOJA_HOME%/bin/doja_g.exeを実行しましょう。すると、前回出てきた携帯の画面に加えて、以下の画面が表示されます。

プロジェクトの新規作成

上記画面で「プロジェクト新規作成」ボタンを押下すると、以下の画面が出てきます。

プロジェクト名を入力して作成ボタンを押下します。ここではhelloとしました。

ビルド

プロジェクトの新規作成によって、C:\iDKDoJa3.0\apps\hello 以下にsrcフォルダが作られているはずです。このsrcフォルダ以下へ前回作成したHelloWorld.javaを置きます。HelloWorldはhelloパッケージに属しているので、実際には src/hello/HelloWorld.java といったように配置します。

ソースファイルの配置が終わったら、iαppliToolの画面上の「ビルド」ボタンを押下します。すると、ソースファイルのコンパイル,クラスファイルの事前検証,Jarパッケージの作成,ADF(JAMファイル)の作成をすべて行ってくれます。非常に楽ちんですね。C:\iDKDoJa3.0\apps\hello\bin 以下に hello.jar, hello.jamが生成されているので、後は実行するだけです。

エミュレータによる動作確認

これも簡単です。iαppliToolの画面上の「起動」ボタンを押下するだけです。

以上のように、iαppliToolを使うとビルドやADF作成の手間が省け、効率良くiアプリの開発ができます。このiαppliToolにはエディタは付属していませんが、外部のエディタを設定することができるので、他のエディタと組み合わせて使うこともできるようです。

今回はiαppliToolの使い方を簡単に紹介しました。次回はDoJaのEclipse向けプラグインの使い方を紹介しようと思います。

このページトップへ

4日目 --- DoJaプラグイン for Eclipseを使ってみる

プロジェクトの新規作成

Eclipseの操作方法については省略します。Eclipseの情報は書籍やウェブに色々とあると思いますので、そちらを参照して下さい。

まずはプロジェクトを新規に作ります。1日目でiアプリ作成ツールのインストール時にEclipseのインストールディレクトリを設定した場合は、Eclipseのメニューから「ファイル」→「新規」→「プロジェクト」を選択すると、以下のように"DoJa-3.0 プロジェクト"が選択できます。

"DoJa-3.0 プロジェクト"を選択し、「次へ」を押下します。

次にプロジェクトの名前を選択します。ここではi-appliとしました。「次へ」を押下して次へ進みます。

すると、上記のようにJava設定画面が表示されます。「ライブラリー」タブを見てみると、インストールしたDoJaプロファイルに含まれるライブラリが選択されています。そのため、ここでも特に何も設定することはありません。「終了」を押下してプロジェクトの作成は終了です。

ADF設定

次に、ADFの設定を行います。Eclipseのメニューから、「ウィンドウ」→「パースペクティブのカスタマイズ」を選択し、「その他」→「DoJa-3.0設定」にチェックを入れます。これで各プロジェクトでADFの設定を行うことができるようになります(下図)。


次に、パッケージ・エクスプローラでプロジェクトを選択し、Eclipseのメニューから「プロジェクト」→「DoJa-3.0設定」を選択します。すると、以下の画面が表示されます。


この画面でAppNameとPackageURL, AppClassを設定します。AppNameにはアプリケーションの名前を、AppClassは実行するクラス名を設定します。PackageURLは"プロジェクト名 + .jar"という名前にします。後のビルドでこの名前でJarファイルが生成されるからです。

コンパイラー準拠レベルの確認

Eclipseはソースファイルを保存するたびにビルドされるので、特にビルド作業を意識する必要はありませんが、そのビルドによって生成されるクラスファイルがどのVMバージョン向けかについては、注意する必要があります。

2日目で書いたことの繰り返しになりますが、iアプリとして動作させるにはJDK1.1と互換性があるクラスファイルが必要です。EclipseがどのVMバージョンに準拠したクラスファイルを生成するかは、ウィンドウ>設定>Java>コンパイラー>準拠およびクラス・ファイル(タブ)のJDK準拠のところで確認できます(下図)。


Eclipse2.xのデフォルト設定では、コンパイラー準拠レベルが1.3になっていると思います。またデフォルト準拠設定の使用にチェックが付いているはずです。ポイントは「生成された.classファイルの互換性」で、ここが1.1になっていればOKです。もしコンパイラー準拠レベルを1.4に変更すると、「生成された.classファイルの互換性」も1.4になってしまい、これではiアプリとして動作してくれません。

デフォルト設定から変更していなければ特に触る必要はありませんが、念のためチェックしておきましょう。

実行

Eclipseのメニューから、「実行」→「実行」を選択します。すると、以下の画面が表示されます。


ここで左上にDoJa-3.0 アプリケーションという項目があります。これを選択して、「新規」ボタンを押下します。すると以下のようにDoJaの設定画面が表示されます。


このアプリケーションの名前を設定し(ここではhelloとしています)、「実行」ボタンを押下します。携帯エミュレータの画面が表示され、HelloWorldと表示されていれば成功です。

今回はDoJaのEclipseプラグインを使う方法を簡単に紹介しました。ここで示したことは最低限の内容です。詳細はiαppliToolのマニュアルを参照下さい。では次回はこれまでに作成したHelloWorldをWebサーバにアップロードして、実機で実行させてみようと思います。

このページトップへ

5日目 --- 実機で動かしてみる

HTMLファイルの作成

携帯電話からサーバ上のiアプリをダウンロードするためには、まずHTMLファイルが必要です。携帯電話でHTMLファイルを表示し、ユーザがその中のリンクを選択することによってADF(JAMファイル)がダウンロードされ、JAMファイルの中に記述されたJarパッケージが更にダウンロードされるという流れになります。

そこで以下のようなHTMLを作成します。

<HTML>
  <BODY>
    <OBJECT declare id="application.declaration" data="hello.jam" type="application/x-jam">
    </OBJECT>
    <A ijam="#application.declaration" href="default.html">HelloWorldアプリをダウンロードする</A>
  </BODY>
</HTML>

<OBJECT>タグの data属性にはJAMファイルのパスを指定します。上記の設定では、HTMLファイルとhello.jamファイルが同じディレクトリにあることを前提としています。<A>タグのijam属性には、<OBJECT>タグのid属性値を指すように設定します。href属性には、Java非搭載機種用メッセージを記述したHTMLのURLを指定します。

アップロード

アップロードするファイルは、JAMファイル,Jarパッケージ,HTMLファイル(Java非搭載機種向けのもの含めて2ファイル)です。今回の例ではこれらすべてをWebサーバ内の同一ディレクトリに配置します。

実行

実際に携帯電話からWebサーバに配置したHTMLをアクセスしてみてください。その中のリンクをクリックして、エミュレータ画面で表示されたような画面が表示されれば成功です。

今回まででiアプリの開発手順とエミュレータでの動作確認、実機での実行方法を紹介してきました。次回以降ではアプリケーションの作成方法を詳しく見ていこうと思います。サーバと通信するアプリケーションの解説も行っていく予定です。

このページトップへ

6日目 --- サーバとHTTPで通信してみる

さて、5日目まででiアプリの基本的な作り方は理解して頂けたでしょうか。後はDojaのユーザインタフェースを押さえて、より高度なアプリケーションを作っていくことになるのですが、ユーザインタフェースなどの解説はすっとばして、サーバと通信する方法を紹介します。筆者の興味が「ユーザインタフェース」<「クライアント-サーバ通信」というのがその理由です。あしからずm(_ _)m。

サーバと通信するには?

iアプリからサーバと通信するためには、GCF(Generic Connection Framework)を使用します。通信プロトコルがHTTPだろうがスクラッチパッドだろうが、接続の方法は同じです。通信プロトコルや接続先に依存しない、汎用的な仕組みを提供してくれるのが、このGCFというわけですね。

具体的にはjavax.microedition.ioパッケージに通信のためのクラス群が用意されているので、このパッケージを使います。

HTTPで通信する

使用頻度が高いのはHTTPプロトコルでしょう。CGIやServletと通信できます。iアプリからWebの掲示板に接続して書き込み・・・なんてことができますね。i-modeでも十分といえば十分ですが、受信パケット量を考慮した場合、アプリケーションに必要なデータのみ受信できるiアプリのほうが、各種のタグを必要とするHTMLに比べて、利用者に優しい(お金の面で)という場合もあるでしょう。今回はiアプリからServletへPOSTリクエストを送信する方法を紹介します。iアプリでHTMLよりも柔軟なGUIを提供して、HTTP POSTで操作結果を送信・・・そんな状況を想定してサンプルの方を紹介していきます。

クライアントプログラム

サーバへHTTP POSTリクエストを送信し、結果を受け取るサンプルプログラムです。やや長めです。

package esc1;

import com.nttdocomo.io.BufferedReader;
import com.nttdocomo.io.HttpConnection;
import com.nttdocomo.ui.*;

import java.io.*;

import java.util.Enumeration;
import java.util.Hashtable;

import javax.microedition.io.Connector;

public class HttpClient extends IApplication {
    public static final String PATH = "servlet/esc1.PostDemoServlet";

    public void start() {
        Display.setCurrent(new HttpClientPanel());
    }

    class HttpClientPanel extends Panel implements ComponentListener {
        Button button = new Button("送信");

        HttpClientPanel() {
            add(button);
            setComponentListener(this);
        }

        public void componentAction(Component source, int type, int param) {
            if (type == Display.KEY_RELEASED_EVENT) {
                if (source.equals(button)) {
                    Hashtable params = new Hashtable();
                    params.put("city", "東京");
                    params.put("tel", "090-XXXX-XXXX");

                    String result = post(PATH, params);
                    showDialog(Dialog.DIALOG_INFO, "受信データ", result);
                }
            }
        }

        private String post(String servletPath, Hashtable params) {
            HttpConnection con = null;
            BufferedReader br = null;
            StringBuffer buf = new StringBuffer();

            try {
                // (1)URL生成
                String url = IApplication.getCurrentApp().getSourceURL() +
                    servletPath;

                // (2)URLオープン
                con = (HttpConnection) Connector.open(url,
                        Connector.READ_WRITE, true);
                con.setRequestMethod(HttpConnection.POST);
                con.setRequestProperty("Content-Type",
                    "application/x-www-form-urlencoded");

                String postData = getQueryString(params);

                // (3)リクエストボディへの書き出し
                writePostData(con, postData);

                // (4)接続
                con.connect();
                int code = con.getResponseCode();
                if (code != HttpConnection.HTTP_OK) {
                    showDialog(Dialog.DIALOG_ERROR, "Error", 
                        "POSTに失敗しました(status code:" + code + ")");
                    return null;
                }

                // (5)受信データの取得
                InputStream in = con.openInputStream();
                InputStreamReader ir = new InputStreamReader(in);
                br = new BufferedReader(ir);
                String s;
                while ((s = br.readLine()) != null) {
                    buf.append(s);
                }
            } catch (Exception ex) {
                showDialog(Dialog.DIALOG_ERROR, "接続エラー", ex.getMessage());
                return null;
            } finally {
                if (br != null) try { br.close(); } catch (IOException e) {} 
                if (con != null) try { con.close();} catch (IOException e) {}
            }

            return new String(buf);
        }

        /**
         * HTTP POSTのリクエストボディに格納する文字列を取得する
         */
        private String getQueryString(Hashtable params) {
            StringBuffer buf = new StringBuffer();
            Enumeration enum = params.keys();

            while (enum.hasMoreElements()) {
                String key = (String) enum.nextElement();
                String value = (String) params.get(key);
                buf.append(key + "=" + value);

                if (enum.hasMoreElements()) {
                    buf.append("&");
                }
            }

            return new String(buf);
        }

        /**
         * リクエストボディへPOSTデータを出力する
         */
        private void writePostData(HttpConnection con, String postData) {
            OutputStreamWriter osw = null;

            try {
                OutputStream out = con.openOutputStream();
                osw = new OutputStreamWriter(out);
                osw.write(postData, 0, postData.length());
            } catch (IOException ex) {
                showDialog(Dialog.DIALOG_ERROR, "Error", ex.getMessage());
            } finally {
                if (osw != null) try { osw.close();} catch (IOException ex) {}
            }
        }

        /**
         * ダイアログを表示する
         */
        private void showDialog(int type, String title, String msg) {
            Dialog d = new Dialog(type, title);
            d.setText(msg);
            d.show();
        }
    }
}
(1)URL生成
接続先のURLを生成します。IApplication.getCurrentApp().getSourceURL()でこのiアプリをダウンロードしたURLを取得し、そのURLにサーブレットへのパスを加えています。iアプリではアプレットと同様に、自身のダウンロード元サーバへのアクセスしか許可されていないため、iアプリが通信するプログラム(今回はServlet)も同じサーバで動作させる必要があります。
(2)URLオープン
Connector#open()でHTTPコネクションを生成し、リクエストメソッドやContent-Typeを設定しています。今回はリクエストメソッドをPOSTとしているので、Content-Typeはapplication/x-www-form-urlencodedとします。
(3)リクエストボディへの書き出し
HTTPリクエストのリクエストボディへ、Servletへ送信するフォームデータを書き出します。HTTP POSTではリクエストのボディ部にフォームデータを書き出します。書き出すデータのフォーマットは、「key1=value1&key2=value2&...keyN=valueN」です。といっても、Servlet側でリクエストボディの内容を単なる文字列として受け取るのであれば、フォーマットは自由です。今回の例ではServlet側でリクエストパラメータとしてリクエストボディの中身を受け取ることを前提としています。ちなみに筆者が参考にした書籍では、URLエンコードを行った文字列をリクエストボディへ格納していました。これは必要なのでしょうか・・・?ここはちょっと自信がないです。
(4)接続
HttpConnectioni#connect()で接続します。HttpConnection#getResponseCode()でHTTPレスポンスのステータスコードが取得できます。成功時は200が返されます。400番台はクライアント側のエラーで, 500番台はサーバ側のエラーです。
(5)受信データの取得
最後にServletから返されたHTTPレスポンスのコンテンツを取得しています。今回使用するServletではテキストデータ(Content-Type=text/plain)を返しますので、ここでは単に文字列として受け取っています。

サーバプログラム

次はiアプリからのリクエストを受信するServletのソースです。Servletについての解説は省略します。今回、iアプリからPOSTリクエストを送信しているので、以下のPostDemoServlet#doPost()が呼び出されることになります。

package esc1;

import java.io.*;

import java.util.Enumeration;

import javax.servlet.*;
import javax.servlet.http.*;

public class PostDemoServlet extends HttpServlet {
    private ServletContext context;

    protected void doPost(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {
        // (1)リクエストパラメータの取得
        request.setCharacterEncoding("SJIS");
        Enumeration enum = request.getParameterNames();
        StringBuffer buf = new StringBuffer();

        while (enum.hasMoreElements()) {
            String key = (String) enum.nextElement();
            String value = (String) request.getParameter(key);
            buf.append(key + "=" + value + ":");
        }

        // (2)レスポンスの生成
        PrintWriter out = response.getWriter();
        response.setContentType("text/plain; charset=SJIS");
        String msg = new String(buf);
        out.print(msg);
        out.flush();
        out.close();
    }

    protected void doGet(HttpServletRequest arg0, HttpServletResponse arg1)
        throws ServletException, IOException {
        doPost(arg0, arg1);
    }
}
(1)リクエストパラメータの取得
クライアントプログラムから送信されるフォームデータをServletAPIを使って取得しています。クライアントがiアプリだからといって特別なことは必要ありません。後でクライアントへ文字列を返すため、ここではリクエストパラメータを連結した文字列を生成しています。
(2)レスポンスの生成
ここではレスポンスのContent-Typeを"text/plain"として、HTTPレスポンスのコンテンツに文字列を格納して返します。

ADF

サーバとHTTPで通信するiアプリを動作させるためには、ADF(jamファイル)に以下のエントリが必要です。

UseNetwork = http

HTTPSで通信する場合は同様に

UseNetwork = https

とします。

動作確認

後はクライアントプログラムを今までと同様Jarパッケージングしてjamファイルと共にWebサーバへアップロードします。サーバプログラムも同じサーバへアップロードし、サーブレット・コンテナ(サーブレットの実行環境)へ適切にデプロイします。

ということは、当然アップロードしたサーバでサーブレット・コンテナが動作していなければなりませんし、動作していなければ動作させなければなりません。しかしCGIと違ってサーブレットを(無料で)動かすことのできるISPは日本国内ではほとんど無いというのが現状です。ただ、海外には無料ホスティングサービスを行っているところがあります。筆者もその一つを使わせてもらって今回の内容の動作確認を行っています。

デプロイ後、まずは携帯端末にiアプリをダウンロードしましょう。途中で通信するかどうかを聞いてくるので通信するように設定して下さい。初期画面は以下のように表示されます(図はエミュレータのものです)。


送信ボタンを押すとサーブレットとの通信が始まり、結果が画面に表示されます。

このページトップへ

7日目 --- 圧縮ツールを使ってみる

何故圧縮が必要?

iアプリの開発では、できあがったJarファイルのサイズも気になるところですね。パケ代を負担するのは利用者なので、できるだけ負担を少なくするためにサイズを削りたいものです。

アプリのサイズを小さくするには、非オブジェクト指向的なスタンスで開発する必要が出てきます。クラス数を少なく、変数名は短くする等ですね。プログラムの見易さを犠牲にしなければなりません。これを開発者が行う場合、本来の機能に集中できなくなるので圧縮ツールを利用するのが良いでしょう。

圧縮ツール

以下の4つのツールを試して見ます。

製品名 特徴 ライセンス サイトURL
Java Blender ・圧縮レベル選択(2種類)
・キャリア選択(標準, 504i, 505i)
・操作方法がシンプル
・オープンソース
フリー(詳細はサイトURLの記述参照) http://web.yl.is.s.u-tokyo.ac.jp/amo/JavaBlender/
jarg ・オープンソース フリー http://jarg.sourceforge.net/index.ja
Retrologic Systems ・リバースエンジニアリング防止が主目的のツール
・オープンソース
LGPL http://www.retrologic.com/
SophiaCompress ・iアプリ, EZアプリ, Vアプリ対応
・圧縮項目のカスタマイズ
1ライセンス30万円 http://www.s-cradle.com/

圧縮結果


圧縮対象は6日目で作成したHTTP通信を行うクライアントアプリケーションです。圧縮結果と実機での動作結果は以下のようになりました。

製品名 圧縮後サイズ(単位:byte) 圧縮率(単位:%) 実機(505i)での動作
Java Blender 2595 32
jarg 2419 37 ×
Retrologic Systems 2951 23 ×
SophiaCompress 2664 30


残念ながら2つのツールで動作しませんでした。「Java Blender」と「SophiaCompress」では共に圧縮率が30%を超えていて、実機でも動作しました。今回圧縮対象としたプログラムは非常にシンプルでクラス数も内部クラスを含めて2つです。もう少し規模の大きいアプリケーションではまた別の結果になるでしょう。ただ、今回のようなシンプルなアプリケーションでも約3割圧縮できるので、有用だと思います。特にiアプリ開発者のように、テストのために何度もiアプリをダウンロードしなければならない人にとってはかなり助かるのではないでしょうか。

このページトップへ

Copyright (c) 2005 OKI Software Co., Ltd.