ウィジェット開発のデバッグ時はブレークポイントで止まらない?!

ウィジェットの開発に興味を持って、二日前ぐらいから情報を集めています。
動作確認の為にサンプルコードを書いたもののうまく動かず…

そこでどこまで動いているか確認する為にブレークポイント置いてデバッグしようとしました。
しかし、どこにおいてもブレークポイントで止まらず…

Activity開発の時は問題なく止まったので不思議に思い、検索。

こんなページがありました。

ブレークポイントでとまらない – 日本Androidの会 | Google Groups

私の探し求める情報ど真ん中でした^^
サービスの場合、onCreate()内に下記のメソッドをいれないと止まらないようです。

android.os.Debug.waitForDebugger();

onCreate()内じゃなくとも、ブレークしたいところの前にいれれば止まりそうですが、生成時が確実か。

クラス配列の初期化構文

Javaのクラス配列(class[])の初期化構文。
今まで知らなかったのでメモとして。

A[] a = null;
a = new A[] {new A(1, 2)};

// 複数指定
a = new A[] {
    new A(1, 2),
    new A(3, 4),
    new A(5, 6)
};

// これはNG
a = {new A(1, 2)};

実際にこういうコード書く事はあまり無いと思いますが、同じように躓いた方はご参考に。

IS01のマルチタップはピンチジェスチャーのみの対応だった?

コメントをいただき、IS01でのピンチジェスチャー(2つの指を開いたり閉じたりで拡大縮小)の使用方法がわかりました。
コメントをくださったmichiさん、情報提供ありがとうございます。

※IS01の独自仕様なので注意
マルチタップ時、MotionEvent#getSize()で2つのタップ箇所の距離を取得できます。
マルチタップしていない時は0になります。

マルチタップ時、MotionEvent#event.getX(), MotionEvent#event.getY()で取得される座標は2つのタップ箇所の中間地点になります。
マルチタップしていない時はタップした座標が取得されます。(当たり前)

この2つの独自仕様を利用して、IS01ではマルチタップ処理(ピンチジェスチャーのみ?)を行うことが出来るようです。

ソースはこちら
SH Developers Square – 2点同時タッチした際の挙動につきまして

上記リンク先では、取得座標が中間地点になる仕様の回避方法として、getSize()が0以上の時にはタッチイベントを無視してくださいと回答されています。
この回避方法しか無いなら、IS01ユーザがマルチタップで誤動作しないように気をつけてくれる事を期待して放置で良さそうですねw

IS01の右メニューの幅

IS01ではアプリ起動時、横向きだと画面右側にメニューが表示されています。(縦向きだと下に表示)
このメニューの幅は106ピクセルなので、アプリの表示領域はFWVGA(854*480)のサイズとなります。

エミュで実行していると気づかないのでご注意ください。
右側のメニューを消す方法もあるようですが、IS01独自のものなので消さずに対応する方が良いでしょう。

IS01のマルチタッチは一般アプリからは使用できない…

IS01に標準搭載されているブラウザではマルチタッチで、拡大・縮小が行えます。
OSのバージョンが1.6なので通常はマルチタッチに対応していないのですが、独自のAPIで機能を実現しているそうです。
独自拡張のためAPIは非公開になっており、一般アプリで使用することは出来ないとのこと。
更にOSのバージョンをあげる事は不可能、と発表があったので今後もIS01ではマルチタッチを使用できないことに。

マルチタッチのアプリを作ろうと思っていたのに残念です。

ソース
「コミュニティの重要さをZaurusで学んだ」、国産Android端末IS01/LYNX設計者と開発者が交流:ITpro
IS01のアップデートは今後行わず KDDIが“発表” – SankeiBiz(サンケイビズ)

タイトルバーとメニューバーを非表示にする方法

デフォルトではAndroidアプリ実行時、タイトルバー・メニューバーが表示されています。
ゲームを制作する場合、どちらのバーも非表示にして画面全体、フルスクリーンモードで実行したいところ。

今回はタイトルバー・メニューバーを非表示にする方法を紹介します。

方法は簡単で、ActivityのonCreate()内に以下のコードを記述するだけ。

Window window = getWindow();

// メニューバーを非表示にする
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

// タイトルバーを非表示にする
window.requestFeature(Window.FEATURE_NO_TITLE);

※setContentView()を呼び出す前に設定すること;

FPSを一定に保つクラスを作成してみました。

Androidでゲームを制作する為に、FPSを一定に保つクラスを作成しました。
(フレームスキップの機能はありません)

スレッドの中で処理を無限ループさせている形を想定しています。

package 好きなパッケージ名で組み込んでください;

import java.util.concurrent.TimeUnit; 
import android.util.Log; 

/** 
* FPSの表示・調整するクラス 
*/ 
public class FPSManager { 
  // 1秒(ナノ秒単位) 
  private static long ONE_SEC_TO_NANO = TimeUnit.SECONDS.toNanos(1L); 

  // 1ミリ秒(ナノ秒単位) 
  private static long ONE_MILLI_TO_NANO = TimeUnit.MILLISECONDS.toNanos(1L); 

  private int maxFps; 
  private int[] fpsBuffer; 
  private int fpsCnt; 
  private long startTime; 
  private long elapsedTime; 
  private long sleepTime; 
  private long oneCycle; 

  /** 
   * コンストラクタ 
   * @param fps 動作FPS 
   */ 
  public FPSManager(int fps) { 
    maxFps = fps; 
    fpsBuffer = new int[maxFps]; 
    fpsCnt = 0; 
    startTime = System.nanoTime(); 
    oneCycle = (long)(Math.floor((double)ONE_SEC_TO_NANO / maxFps)); 
  } 

  /** 
   * 状態更新 
   * @return sleepする時間(ナノ秒) 
   */ 
  public long state() { 
    fpsCnt++; 
    if (maxFps <= fpsCnt) { 
      fpsCnt = 0; 
    } 

    elapsedTime = System.nanoTime() - startTime; 
    sleepTime = oneCycle - elapsedTime; 

    // 余裕が無い場合でも1ミリ秒はsleepさせる 
    if (sleepTime < ONE_MILLI_TO_NANO) { 
      sleepTime = ONE_MILLI_TO_NANO; 
    } 

    int fps = (int)(ONE_SEC_TO_NANO / (elapsedTime + sleepTime)); 
    fpsBuffer[fpsCnt] = fps; 

    startTime = System.nanoTime() + sleepTime; 

    return sleepTime; 
  } 

  /** 
   * FPSの取得 
   * @return 現在のFPS 
   */ 
  public int getFps() { 
    int allFps = 0; 
    for (int i = 0; i < maxFps; i++) { 
      allFps += fpsBuffer[i]; 
    } 

    return allFps / maxFps; 
  } 
}

使い方。
まずは初期化。

// FPS:30で動作させる
FPSManager fpsM = new FPSManager(30);

一定間隔で実行したいThreadのRun()メソッド内で

TimeUnit.NANOSECONDS.sleep(fpsM.state());

を呼ぶ。
以上。

Androidアプリ、パフォーマンス向上関連の記事

Android Techfirm LabにAndroidアプリのパフォーマンス向上に役立つ記事がありました。

Android NDKを使用してJava言語とC言語で速度比較をする | Android Techfirm Lab
重い処理の部分だけC言語で記述し高速化を図る方法です。

@ITでは、Android NDKの導入方法も含めて詳しく解説されていました。
Android NDKでJNIを使用してアプリを高速化するには (1/3) – @IT

いいことばかりではないので、どうしても処理が重い時の対処法として覚えておくと良いかも。

他のパフォーマンス向上記事もいくつか。
基本が大事ですね。

Android開発でのパフォーマンスTips(1) | Android Techfirm Lab
Android開発でのパフォーマンスTips(2) | Android Techfirm Lab
パフォーマンス向上に役立つ情報いろいろ | Android Techfirm Lab

Androidの描画クラス

Androidの描画クラスは3つあります。

・View
基本の描画クラスです。
ボタンやテキストフィールド、チェックボックスなどの部品を配置して作るツールの描画に適しています。

・SurfaceView
2Dのゲームやリアルタイムに描画をする必要があるアプリの描画に適しています。

・GLSurfaceView
3Dのゲームやリアルタイムに描画をする必要があるアプリの描画に適しています。

Android携帯の解像度まとめ

日本で発売・発売予定のAndroid携帯の解像度をまとめました。

HVGA(320*480)
・HT-03A(docomo)
・Optimus chat L-04C(docomo)
・004HW(softbank)

WVGA(800*480)
・IS06(au)
・LYNX 3D SH-03C(docomo)
・GALAXY S SC-02B(docomo)
・HTC Desire X06HT(softbank)
・HTC Desire X06HTⅡ(softbank)
・HTC Desire HD 001HT(softbank)
・DELL Streak 001DL(softbank)
・Libero 003Z(softbank)
・GALAPAGOS 003SH(softbank)
・GALAPAGOS 005SH(softbank)

FWVGA(854*480)
・IS04(au)
・IS05(au)
・Xperia X10 SO-01B(docomo)
・REGZA Phone T-01C(docomo)

FWVGA++(960*480)
・IS01(au)
・LYNX SH-10B(docomo)

ダブルVGA(640*960)
・IS03(au)

WSVGA(1024*600)
・GALAXY Tab SC-01C(docomo)

WVGA・FWVGAが主流のようです。
主流のWVGAと最小サイズのHVGAをフォローすれば、全機種で操作しやすいアプリを作れそうですね。