DoJa で Bad Method Signature

Javaアプレットからの移植作業関係で, DoJa エミュレータでは問題ないのに実機だと表題の例外が出る、という現象に遭遇。
調べてみると、float や double を利用している場合に出るとのことだが、ソースに対して単語検索をかけてもヒットしないし、一見全く利用していないように見える。
..が、やはり違う形で参照していて、次のようなケースも NG でした。
 
– 数値リテラルが float, double を表している。
ex. 3.5, 5., 5f
– Math.floor() など float, double を返すメソッドを呼び出している。
※これでもコンパイルは通るしエミュレータでも動作してしまう。

デフォルトの動作で iアプリで画面がすぐ暗くなる問題の対処

問題:
  バックライトがオフになり暗くなる。
対策:

com.nttdocomo.ui.PhoneSystem.setAttribute(0, 1);

を定期的に呼んでやればよい。(第一引数の 0 は DEV_BACKLIGHT, 1 は on)

DataOutputStream 関係の仕様

– DataOutputStream.write(byte[] str, int offset, int len) は offset + len が str.length() を超えると ConnectionException が投げられる。

        try {
            DataOutputStream out = Connector
                    .openDataOutputStream(“scratchpad:///0;pos=0”);
            out.write(“Something”.getBytes(), 1, 20); // OK
out.write(“foo”.getBytes(),0,4); // Error!!
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

i アプリに必要なADF(.jam) 記述

– AppClass = Foo
IApplication を継承している実行クラス。必須。
– PackageURL = foo.jar
アプリを格納している jar ファイル。相対ディレクトリ指定、URL 表記ともに可能。必須。
– AppSize = 12345
PackageURL で指定したファイルのサイズをバイト単位で正確に指定する。必須。
– SPsize = 102400
確保する必要のあるスクラッチパッド領域をバイト単位で指定する。必須。
– LastModified = Mon, 07 Nov 2005 16:00:00
更新時刻。

WWW, DD MMM YYYY HH:mm:ss

という表記をとる。503i 系対応にするときは月に Apr を指定してはならない。必須。
i アプリのバージョンアップ時にチェックされる。
– UseNetwork = http
i アプリ上で Web アクセスする場合に必須
– UseBrowser = launch
i アプリ上でブラウザを立ち上げる場合に必須
– AppVer = X.X
バージョン指定。必須?
– AppTrace = On
指定すると携帯端末でデバッグ出力(トレース情報, ダウンロード元 URL 等)を表示するようになる。
トレース表示の仕方は機種によって全く異なるため、<http://www.saturn.dti.ne.jp/~npaka/ibook2/izon.html> の各バージョンについての「待ち受けボタン・トレースの表示」を参照。

i アプリのダウンロードに必要な HTML 記述

最低限必要なのは次の表記:

  <!–
    – 参照用の id(“fooId”) と jam ファイル(“foo.jam”)を結びつける。
    –>
  <object declare id=”fooId”
          data=”foo.jam”
          type=”application/x-jam”>
  </object>
  
  <!–
    – ダウンロードのためのリンク。
    – ijam に指定した ID(“fooId”) に関連づけられているアプリケーションをダウンロードする。
    – i アプリ対応していない端末からアクセスした場合は href に指定した error.html にリンクする。
    –>
  <a ijam=”#fooId” href=”error.html”>Download</a>

DoJa エミュレータでオプションとなっている API を使うと例外が出る

少し前にはまった。DoJa エミュレータのデフォルトではライブラリが不足しているので呼び出そうとすると RuntimeError になる。エミュレータ上で正しく動作させるには micro3d_v2_32.dll というファイルを DoJa の bin フォルダにいれてやる必要がある。
<http://www.mascotcapsule.com/toolkit/docomo/>
– micro3d_v2_32.dll の配布元。
– 追記 2005-12-19: ダウンロード場所がわかりにくい気がするので捕捉。現在、
DoJa 2.5oe/3.0/3.5 の Tools -> DLL micro3d_v32.dll でダウンロード可能。

DoJa プロジェクトの最小構成要素

Eclipse + iαppliTool for DoJa-X.X を使って開発しているのだが、
Eclipse の DoJa プラグインを使わずに新規プロジェクトを作るときに何が必要なのか毎度忘れるのでメモ。(DoJa 4.0 で確認)
 注: prefix の + はディレクトリ, – はファイルをあらわす事にする。
 +projectname – プロジェクト名と同じディレクトリ名
   -projectname – プロジェクト名と同名のファイル(拡張子なし)
   -projectname.properties – プロジェクト名と同名のファイル(拡張子 .properties)。 なくても動作はするが、これがないとファイル配置など設定が保存されない。
   +src – ソースフォルダ(*.java)
   +bin
     -projectname.jam – プロジェクト名.jam
   +res – リソースディレクトリ(resource:///filepath でのアクセス用)
Eclipse で作業する時は、リリースディレクトリを bin ではなく classes 等にすると干渉しない。また Eclipse で必要な設定は次の通り。
 
– リリースディレクトリを bin でなく classes にする。
  任意。DoJa との干渉を防ぐため
– JDK のコンパイラ互換性関係のオプションをバージョン 1.1 に近づける。
  任意。DoJa の動作する J2ME は JDK1.1 相当のため, Eclipse で通るものが DoJa のビルドでエラーになってしまったりする。そのためできるだけバージョンを下げておくのが望ましい。
– Java のビルドパスに DoJa のライブラリ(classes.zip, doja_classes.zip)を追加しておく。
  必須。DoJa をインストールすると DoJa のインストールディレクトリの /lib 以下にあるもの。
lib/profile の中のものは旧バージョンのライブラリ。

HTML のような画像敷き詰めをするメソッド

– ゲームを作っていると背景などで同じ画像をタイル状に張る処理をよくやるのでメソッド化してみた。なかなか便利。とりあえず DoJa 用だが、ImageObserver を渡してやる部分をくっつければすぐに AWT 用に移植できるはず。

    /**
     * イメージを指定範囲に敷き詰める.
     *
     * @see Graphics#drawImage(com.nttdocomo.ui.Image, int, int)
     * @see Graphics#fillRect(int, int, int, int)
     *
     * @param g 敷き詰め先
     * @param img 敷き詰める画像
     * @param x 敷き詰め先左上 X 座標
     * @param y 敷き詰め先左上 Y 座標
     * @param w 敷き詰め先の幅
     * @param h 敷き詰め先の高さ
     * @author hiro.I
     * @since 2005-10-20 18:12:31
     */
    public static final void fillImage(Graphics g, Image img, int x, int y,
            int w, int h) {
        final boolean bHasHorizonalFraction = w % img.getWidth() > 0;
        final boolean bHasVerticalFraction = h % img.getHeight() > 0;
        final int COLS = w / img.getWidth() + (bHasHorizonalFraction ? 1 : 0);
        final int ROWS = h / img.getHeight() + (bHasVerticalFraction ? 1 : 0);
        for (int i = 0; i < ROWS; i++) {
            final int ty = y + i * img.getHeight();
            final int th = (i == ROWS – 1 && bHasVerticalFraction ? h
                    % img.getHeight() : img.getHeight());
            for (int k = 0; k < COLS; k++) {
                final int tx = x + k * img.getWidth();
                final int tw = (k == COLS – 1 && bHasHorizonalFraction ? w
                        % img.getWidth() : img.getWidth());
                g.drawImage(img, tx, ty, 0, 0, tw, th);
            }
        }

    }

キーイベント処理中に時間のかかる処理をすると Canvas.processEvent が呼ばれなくなる

たとえば Canvas の子クラスで processEvent(int,int) を次のような実装をしたとする

public void processEvent(int type, int param){
    System.out.println(“processing…”);
    for(;;){// forever
        try {
            Thread.sleep(1000); // メイン処理。1秒待つのを繰り返すだけ
        } catch( InterruptedException e ) {
            IApplication.getCurrentAPp().terminate(); // 割り込みで終了
        }
    }
    System.out.println(“end of process”);
}

実行結果は一見、キーを押した数だけ processing… とだけ表示されるように思われるが、実際は processing…