2008年01月31日

Androidで「通信中」みたいなダイアログを表示する

プログレスダイアログ 時間のかかる処理、例えばネットから何かをダウンロードするアプリを作る場合、「通信中」「ダウンロード中」などのダイアログを表示し、キャンセル可能な状態にした上で、別スレッドを起動して実際の通信処理を行うということがよくあります。

Androidなら、メインのActivityから時間のかかる処理を行うThreadを生成し、そのrun()の最後に、メインのActivityへ終了を通知、Activityはダイアログを閉じる、といった流れになるかと思いますが、androidでこのまま実装してしまうと「Only the original thread that create a view hierarchy can touch its view.」というエラーになってしまいます。

ようはActivity自身のスレッドのみがそのビューを変更できる、ということのようです。Androidはいちいちメッセージが丁寧でありがたいです。

じゃあAndroidではどうするのかということですが、Handlerクラスとそのpost()メソッドを使用します。

例えば、ActivityにRunnableを実装しておき、run()メソッドにはダイアログを閉じる処理を書いておきます。一方、時間のかかる処理を実行するThreadにはhandlerオブジェクトとRunnableを実装したActivityを渡します。そしてThread#run()の最後で「handler.post(activity);」とかすれば、処理の終了時にちゃんとダイアログを閉じることができます。


ソースコードにするとこんな感じ。

public class MyActivity extends Activity implements Runnable
{
    private final Handler handler = new Handler();

    private ProgressDialog dialog;

    // 中略

    private void doSomething()
    {
        // プログレスダイアログを表示
        dialog = new ProgressDialog(this);
        dialog.setIndeterminate(true);
        dialog.setMessage("Now in progress.");
        dialog.show();

        // 時間のかかる処理を実行するスレッドをスタート
        doSomethingThread = new DoSomethingThread(handler, this);
        doSomethingThread.start();
    }

    public void run()
    {
        // ダイアログを閉じる
        dialog.dismiss();
    }
}

public DoSomethingThread() extends Thread
{
    private Handler handler;

    private final Runnable listener;

    public DoSomethingThread(Handler _handler, Runnable _listener)
    {
        this.handler = _handler;
        this.listener = _listener;
    }

    @Override
    public void run()
    {
        // 時間のかかる処理

        // 終了を通知
        handler.post(listener);
    }
}

以上、こちらの記事に書いてあることをかみ砕いてみました。
イマドキのAndroidアプリケーション開発方法

2008年01月29日

androidで2chブラウザ

実機がないくせに開発環境は揃いまくっているgoogle-phoneのプラットフォーム「android」ですが、先日ドコモとの業務提携も決まり、国内での「android」対応機の販売もにわかに現実味を帯びてきました。

NTTドコモとグーグルが提携、検索機能を強化しAndroid対応機も開発

実機がないんじゃ作ってもつまんないし……と思ってたんですが、徐々にandroidの情報サイトも増えてきて、自分みたいな初心者でも開発できる雰囲気になってきたので、何か作ってみようと。それでどうせなら2chブラウザを作ってみることにしました。何故なら「android開発」と「2chブラウザの作り方」が一度に学べちゃって一石二鳥なのです。

まずandroidのキホン的なものはこちらのサイトで。
Android入門

SDKに付属のNotepadを作成するチュートリアルをかみ砕いて和訳されている便利な記事もあります。
Androidアプリケーション開発入門

英語ですが、こちらはいろいろなチュートリアルがあって絶対役に立つ感じ。
anddev.org

androidはこれだけあれば大丈夫ということで、次は2chブラウザを作るに当たってはこちらの記事。この記事を見付けたから2chブラウザ作ろうと思いました……。
2chビューアを作成するための知識

これらのサイトを見れば簡単に上記スクリーンショットみたいなブラウザが作れました。といっても板とスレッドを選んで中身をやっと表示できるだけですが。レスをどうやって表示しようか迷ってます。androidはWebViewというのがあってHTMLを簡単に表示できるんですけど、なんか大げさですしね。

えーとここまで作ってandroidのわかったこと。

  1. androidではアプリケーションの1画面分を「Activity」というクラスで定義する。アプリケーション自体もまずメインのActivityが起動され、必要に応じてサブ画面(この2chブラウザなら板を選んだ後のスレッドリスト画面)のActivityをstartSubActivityメソッドとかで呼び出す。
    ちなみにActivityにはリスト表示に適したListActivityとかもある。
  2. Activityを構成するコンポーネントみたいなもの(ラベルとかボタンとか)はandroidでは「View」というらしい。
  3. androidではメニューのラベルだとかの文字列リソースはプロジェクトのres/values/strings.xmlで定義できる。ファイルを変更すると、自動的にRというクラスが更新され、例えば「R.string.menu_label_exit」みたいな感じでリソースIDを取得できる。
  4. 2と同様、Activityのレイアウトもxmlで定義すると便利。res/layoutフォルダ内にxmlファイルを作ってレイアウトを定義でき、Activity#setContentView()メソッドでそのレイアウトを設定できる。
    レイアウトで定義したViewは「button1 = (Button)findViewById(R.id.button_a);」とかで取得できる。

なおここに記載されている内容は間違っている可能性が大いにありますのでご注意下さい。

2007年10月17日

Javaアプリケーションで、ESCキーを押したときにダイアログを閉じる

NetBeansを使ってみてからというもの、これまでDelphiで作ってたやつ全部Javaに移植したいぐらいの勢いでJava大好きになってしまいました。ポトリペタが可能なGUIのエディタはDelphi6のそれなんかより圧倒的に使いやすく(最近のDelphiは知りませんが)、もはやどうしてもWin32APIを使わなければならない場合を除いてDelphiを使う理由がありません。

しかしながらやはりJava、Windowsネイティブのアプリケーションと比べると操作や見た目で差違が出てしまい、使う時に違和感があります。ファイルダイアログなんかは似てはいるものの、Windowsのシェルメニュー等が使えずかなり不便です。

ダイアログもそうで、Windowsでは標準の動作としてESCキーでダイアログが閉じます。設定をキャンセルする時などよく使うのですが、SwingのJDialogではそうはなりません。ですがありがたいことにこれはごくわずかなコードで可能になります。

InputMap imap = getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
imap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "escape");
getRootPane().getActionMap().put("escape", new AbstractAction(){
  @Override
  public void actionPerformed(ActionEvent e) {
    dispose();
  }
});

JDialogのインプットマップにESCキーを追加し、そのアクションに閉じる処理を追加します。このコードではdispose()ですが、破棄する必要がなければsetVisible(false)でもなんでもいいと思います。大事なのはgetInputMap()のWHEN_IN_FOCUSED_WINDOWで、これを指定することでウィンドウ内のどのコンポーネントにフォーカスがあろうが、ESCキーが有効になります。Windowsのネイティブの動作と同じです。

ちなみに、ダイアログがESCキーで閉じるのはWindows固有の動作のようなので、こうやって無理に対応させるよりはあえて非対応にしておく方がマルチプラットフォーム対応と言えるのかもしれません。でもやっぱ閉じる時はESCキー押しちゃうし。

2007年01月20日

ImageMagickのリファレンス

文字入りQRコード作成サービス「MOJI-Q」ですが、QRコード作成に関してはswetake.comのQRcode Perl/CGI & PHP scripts ver. 0.50を使わせていただきました。とくに何の予備知識もいらず、プログラムからQRコードが作成できてしまいます。感謝。

swetake.com
http://www.swetake.com/

なお、QRcode Perl/CGI & PHP scriptsを使ってプログラムからQRコードを作成する時のとっかかりとしてはITProのこちらの記事も役立ちます。PHPですが。
第3回 PHPでQRバーコードを作成する(その1)
第4回 PHPでQRバーコードを作成する(その2)

そして、文字入れの処理にはImageMagickを使っています。GDと並んでPHPやPerlから画像処理がすげー簡単に、高機能に出来てしまうライブラリですが、何しろドキュメントがないと使い方がさっぱりわからないので、下記のサイトが便利です。自分はPerlを使ったので、どちらもPerlMagickのリファレンスです。

ImageMagick: PerlMagick, Perl API for ImageMagick
http://www.imagemagick.org/script/perl-magick.php
何しろ英語。でもリファレンス的に使う分にはそんなに困らないです。網羅されてますし。

PerlMagickリファレンス
http://www.ss.iij4u.or.jp/~somali/web/_perlmagick_ref.html
上記サイトを翻訳してくれていますが、完璧ではありません。それでも日本語なのでざっと機能を探すにはとても便利。

2006年12月24日

Eclipseでfeature.xmlのエラー

eclipseに新しいプラグインをインストールしようとして、Software Updates→Find and Install...を実行した時にこんなエラーメッセージが出ました。

Problem Occurred
Error retrieving "feature.xml". [error in opening zip file]

こちらのブログによると、eclipse.exeがあるフォルダのsite.xmlがいけないらしいです。削除したらエラーは出なくなりました。めでたし。

2006年10月08日

Javaで圧縮ファイルを作る時の注意

ノベリオンは処理の中でJARファイルを出力するんですが、JARファイル内(つまりZIP圧縮したファイル)の中身が文字化けのような形で、アスキー文字は無事、その他のバイナリ部は壊れてしまうという現象が起きました。

結論から言うとZipEntryに対して、setSizeやsetCrc、setCompressedSizeなどの処理を忘れるとそういう風になってしまうみたいです。ZipOutputStream、JarOutputStreamを使う時の注意ですねー。

このページのサンプルが参考になります。
http://homepage3.nifty.com/akaho/program/java/zip/index.html

2006年04月27日

メニューがキャンバスの後ろに隠れてしまう

Javaプログラミングで、SwingのJMenuとAWTのCanvasを組み合わせて使ってしまうと、ドロップダウンしたメニューがキャンバスの後ろに隠れるため見えなくなってしまいます。解決策としては、Canvasの代わりにSwingのJPanelを使います。
これくらいは常識なんでしょうね。自分はすっかり悩んでしまいましたが。

2006年04月16日

Java Canvasでダブルバッファリング

キャンバスへの描画時にちらつきを押さえるためにダブルバッファリングをするんですが、 単純にオフスクリーンバッファを生成してそこに描いてから転送すればいいんだろ、と思ったら違いました。
もう一つ、updateメソッドをオーバーライドしないといけないんですね。 元のupdateメソッドに背景色で塗りつぶすという処理があって、それを回避しないといけないらしいです。

Google検索「Java ダブルバッファリング」

2004年08月23日

待受画像に再配布不可識別子を付けるには

待受画像に著作権保護フラグをつければ、携帯にダウンロードした後、再配布できなくなります(メールに添付したりできない)。ドコモのimodeでは再配布不可識別子、auのEZwebでは転送不可情報などとかかれています。それらを付ける方法です。

ドコモの場合
GIF、JPEGファイルのコメントブロックに「copy="NO"」と記述する。
詳細な方法

auの場合
GIF、JPEG、PNGのコメントブロックに「kddi_copyright=on」と記述する。
詳細な方法

2004年08月18日

空間における2点間の距離('03.10.15)

これは参考書などに公式として必ず載ってますので簡単です。SANDMAN氏のs_mathpackにもNowDistance関数として入ってます。

2点A(ax, ay, az)、B(bx, by, bx)の間の距離は
|AB| = √ {(bx - ax)2 + (by - ay)2 + (bz - az)2}

また原点O(0, 0, 0)とA(ax, ay, az)の間の距離は
|OA| = √ {ax2 + ay2 + az2}

これをDelphiで書くと、
D := Sqrt(Sqr(b.x - a.x) + Sqr(b.y - a.y) + Sqr(b.z - a.z));

また、原点からの距離は単純に、
D := Sqrt(Sqr(a.x) + Sqr(a.y) + Sqr(a.z));

広告


この広告は60日以上更新がないブログに表示がされております。

以下のいずれかの方法で非表示にすることが可能です。

・記事の投稿、編集をおこなう
・マイブログの【設定】 > 【広告設定】 より、「60日間更新が無い場合」 の 「広告を表示しない」にチェックを入れて保存する。