SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Android開発のためのJava SE再入門

java.langパッケージとグラフィックの基本処理

Android開発のためのJava SE再入門(4)

  • X ポスト
  • このエントリーをはてなブックマークに追加

スレッドを用いたアニメーション処理サンプル

 今回紹介するサンプルを実行させると、次のような青い線の円が、時計のように円を描いてアニメーションするというものです。Androidでアニメーションを行うには、いくつかの方法がありますが、今回はThreadクラスを用いて処理します。

図1 起動画面
図1 起動画面

独自のビュー

 サンプルのソースコードは、2つのクラスから構成されています。ひとつは、Activityクラスを継承したHelloAndroidクラス、もうひとつは、そのHelloAndroidクラス内で定義している、Viewクラスを継承したDrawViewSampleクラスです。

 HelloAndroidクラスでは全体的な処理、DrawViewSampleクラスではスレッドを用いたグラフィック描画処理(円の表示)を記述しています。

 スレッド部分の説明の前に、まずは、HelloAndroidクラス全体を見てみましょう。

リスト1 HelloAndroid.javaの一部
public class HelloAndroid extends Activity {

    // 独自のビュー
    DrawViewSample v;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        v = new DrawViewSample(getApplication());
        setContentView(v);
    }

    @Override
    protected void onResume() {
        super.onResume();
        v.onResume();    // スレッド生成、開始の呼び出し
    }

    @Override
    protected void onPause() {
        super.onPause();
        v.onPause();     // スレッド終了の呼び出し
    }

    class DrawViewSample extends View {
        ~中略~
    }
}

 今回のサンプルでは、描画処理をすべてソースコードで記述できるように、ビューをXMLから生成するのではなく、動的に定義して生成しています。それがDrawViewSampleクラスです。

 HelloAndroidクラスでオーバライドしているonResume、onPauseメソッドは、第2回目に説明したように、自動的に呼ばれるメソッドです。onResumeメソッドは、Activityが表示される直前、onPauseメソッドは、Activityが最前列でなくなったときに呼ばれます。

 一般にonPauseメソッドでは、変更情報の保存やアニメーションの停止処理を記述します。なおActivityが再び前面に表示されると、またonResumeメソッドが呼ばれます。

 サンプルコードでは、それぞれのタイミングで、スレッドの生成、開始と、終了の呼び出しを行っています。

グラフィックの描画

 Androidでのグラフィックを描画する基本的な考え方は、AWTやSwingを使ったデスクトップのJavaアプリケーションと同じです。つまり、画面の表示を更新する際に呼び出されるメソッドがあり、そのなかで描画処理を記述します。Androidでは、ViewクラスのonDrawメソッドが、そのメソッドに相当します。

 次のコードは、DrawViewSampleクラスから、onDrawメソッドの部分だけを抜粋したものです。

リスト2 DrawViewSampleクラスのonDrawメソッド
class DrawViewSample extends View {

    @Override
    protected void onDraw(Canvas canvas) {
        // 描き方の指定
        Paint paint = new Paint();
        paint.setColor(Color.BLUE);
        paint.setStrokeWidth(2);
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.STROKE);

        // 座標の設定
        double r = toRadians(6 * this.ix);
        double x = 100 + 50 * cos(r);
        double y = 100 + 50 * sin(r);

        // 線で円を描く
        canvas.drawCircle((float)x, (float)y, 5, paint);
    }
}

 onDrawメソッドでは、Canvasクラスのオブジェクトが渡されます。Canvasオブジェクトとは、いわゆるグラフィックコンテキストで、描画のためのメソッドが多数用意されています。サンプルの円の描画は、CanvasクラスのdrawCircleメソッドを利用しています。drawCircleメソッドは、引数として、座標、半径、描き方を指定します。

 Paintクラスは、図形の描き方に関する設定を行います。ここでは、円の色、線の幅、線のスタイルなどを指定しています。

 座標の設定では、前述したMathクラスの三角関数を用いて、円弧の座標を求めています。

スレッド処理

 次に示すコードは、DrawViewSampleクラスの残りの処理、つまりスレッド処理の部分です。

リスト3 DrawViewSampleクラスのスレッド処理
class DrawViewSample extends View {

    int status = 0; // 状態管理変数
    int ix = 0;
    Thread timer;

    // (1)スレッドとして実行したい処理の定義
    Runnable task = new Runnable() {
        public void run() {
            // statusが0の間実行する
            while (status == 0) {
                ix++;                  // 座標更新のためインクリメント
                postInvalidate();      // 画面更新依頼
                try {
                    Thread.sleep(100); // 100ミリ秒間待機
                } catch (InterruptedException e) {
                }
            }
        }
    };

    // (2)スレッドの開始
    public void onResume() {
        timer = new Thread(task); // Threadクラスのインスタンス化
        timer.start();            // スレッドの開始
    }

    // (3)スレッドの終了
    public void onPause() {
        status = 1;               // スレッドを終了させる
        try {
            timer.join();         // スレッドが終了するまで待機
        } catch (InterruptedException e) {
        }
    }
}

 (1)では、無名クラスを用いてRunnableインタフェースを実装しています。(2)は、Threadクラスのインスタンス化と、スレッドの開始、(3)は、スレッドの終了処理で、Threadクラスのjoinメソッドを使って、スレッドが終わるまでアプリケーションを待機させています。なお今回の例では、このjoinメソッドでの待機を省いても問題ありません。ただし、スレッドが終わる前にアプリケーション本体が終了してしまう、といった事態を防ぐために、通常joinメソッドで待機するようにします。

スレッドの内容

 スレッドとして実行している処理は、実質として、ix++とpostInvalidateメソッドの呼びだしの2行だけです。次のsleepメソッドは、処理の間隔をあけるために、スレッドを待機させます。

 変数ixのインクリメントは、円弧の座標を進めるためです。postInvalidateメソッドとは、Viewクラスで定義されたメソッドで、画面の再描画をリクエストします。画面を無効にし、描き直すようにAndroidに伝えるのです。このメソッドを受けて、Androidでは再描画処理を行い、onDrawメソッドが呼ばれます。onDrawメソッドで描画するたびに、円の座標が進んでいるため、動いているように見えるというわけです。

 ただこの場合の再描画は、即座に行われるわけではありません。そのため、サンプルのアニメーションも若干ギクシャクした動きになっているはずです。このあたりの仕組みは、また回をあらためて説明することにしましょう。

最後に

 今回は、java.langパッケージを中心に、スレッドとグラフィックの基本処理を解説しました。次回は、ジェネリクスやコレクションクラスを中心に紹介することにします。

参考資料

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Android開発のためのJava SE再入門連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト 高江 賢(タカエ ケン)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/6078 2011/08/18 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング