SurfaceViewで使用する画像を読み込む


これは、キャンバス系のView全般で使えるメソッドで、別にSurfaceViewに限ったものではありません。
画面の大きさに左右されず一定の比率でBitmapを生成しています。
注意すべきは生成のタイミングで、Viewを呼び出すタイミングで一回だけ生成するようにしてください。
特にSurfaceViewだとコード内でループしているので、何度も画像生成するようなタイミングでメソッドを呼び出さないように注意してください。

自分の場合は、
public void run() {
すぐあとくらいの行で記述しています。
while(true)の中に入れないように。

[AnimationSurfaceView.java]

//宣言は別の場所で
Bitmap bm[];
・
・
・
	@Override
	public void run() {
・
・
・
		//画像の読み込み
		Resources res = getResources();
	    bm = new Bitmap[Const.IMAGE_ID.length];
	    for (int i = 0; i < bm.length; i++) {
	    	System.out.println("i ->" + i);
	    	bm[i] = Const.exchangeImage(screen_width, screen_height, res, Const.IMAGE_ID[i]);
	    }
・
・
・

定数やメソッドをまとめて記述しているConstクラスを別ソースで保存します。
[Const.java]

	//AndroidにおいてはEnumは使うべきではない
	public static final int IMAGE_BG		= 0;
	public static final int IMAGE_WAKU		= 1;
	public static final int IMAGE_BAR		= 2;
	public static final int IMAGE_BALL		= 3;
	public static final int IMAGE_BLOCK1	= 4;
	public static final int IMAGE_BLOCK2	= 5;
	public static final int IMAGE_BLOCK3	= 6;

	public static final int[] IMAGE_ID = {
		R.drawable.bg,
		R.drawable.waku,
		R.drawable.bar,
		R.drawable.ball,
		R.drawable.block1,
		R.drawable.block2,
		R.drawable.block3,
	};
	
	public static Bitmap exchangeImage(int width, int height, Resources resources, int id) {
		//拡縮の倍率
		float magni_x = (float)width / IMAGE_WIDTH;
		float magni_y = (float)height / IMAGE_HEIGHT;
		
	    //拡縮して生成
	    Matrix matrix = new Matrix();
	    matrix.postScale(magni_x, magni_y);
	    
	    BitmapFactory.Options options = new BitmapFactory.Options();
	    options.inScaled = false;
	    options.inJustDecodeBounds = false;
	    Bitmap _bm = BitmapFactory.decodeResource(resources, id, options);
	    Bitmap bmp = Bitmap.createBitmap(_bm, 0, 0, _bm.getWidth(), _bm.getHeight(), matrix, true);
	    _bm.recycle();
	    _bm = null;
	    return bmp;
	}

このConst.javaの中の
R.drawable.bg

R.drawable.bar
が、画像ファイルです。
IDをint型配列の中にまとめておきます。
こうすることで、画像が減ったり増えたりしても、Constをいじるだけですぐに対応できます。

で、問題は画像の配列の添え字を別に
public static final int IMAGE_BG = 0;
public static final int IMAGE_WAKU = 1;
このように定義している件です。
これはコメントにも書いてある通り、AndroidアプリにおいてはEnumは使うべきでないという判断からこうしています。
なぜEnumを使ってはダメかというと、詳しくはググってください。負荷対策らしいです。
少々面倒ではありますが、Androidアプリ開発において、メモリリークとの戦いは常につきまとう問題です。
こういう所から意識していきましょう。

カテゴリー: Android, Java, プログラム

コメントを残す

メールアドレスが公開されることはありません。