ウニのサバト

今日もリセット

なんだかオフスクリーン出来たっぽい?

2013-12-09 02:51:40 | Android

Android アプリではSurfaceViewというのがあって、
そこで描画処理を行えばいいみたいだ。

しかもCanvasにBitmapをペタペタ貼り付けて、
一気に画面に展開できる。

つまり標準でオフスクリーンを持っているのだ。

だが、ちょっと詰まった。
SurfaceViewを生成したタイミングで
surfaceCreated()が呼ばれるハズなのに呼ばれない。
色々試したがどうにも呼ばれないし
getHolder()の戻り値がnullで先に進めなくなった。
コールバックが上手く設定できていないのか?

ウギギ・・・。

仕方がないので、プロジェクトを再作成して
SurfaceViewを実装してみるとちゃんと動いた。
なんでやねん。

ちゃんと動いたので、スレッドを立てるようにして、
その中で定期的に描画を行うようにした。

自分用にざっくりサンプルを残そう・・・。
ソースコピペ時のインデント直すのメンドイ・・・


◆アクティビティ
public class MainActivity extends Activity {

 MySurfaceView mSfV;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  //画像処理
  Paint paint = new Paint();
  Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.dice1);
  
  mSfV = new MySurfaceView(this);
  setContentView(mSfV);
  
  mSfV.setOffScreenBmp(bmp);
  mSfV.setRefreshFlg(true);
  
  Bitmap bmp3 = Bitmap.createBitmap(480, 320, Bitmap.Config.ARGB_8888);
  Bitmap bmp2 = BitmapFactory.decodeResource(getResources(), R.drawable.dice2);

  Canvas ofs = new Canvas(bmp3);
  ofs.drawBitmap(bmp2, 0, 0, paint);
  ofs.drawBitmap(bmp, 100, 50, paint);

  mSfV.setOffScreenBmp(bmp3);
  mSfV.setRefreshFlg(true);
  }

 protected void onDestroy() {
  super.onDestroy();
  // Toast.makeText(this, "onDestory", Toast.LENGTH_SHORT).show();
  //スレッドの停止
  mSfV.StopThread();
 }
}

◆SurfaceView

public class MySurfaceView extends SurfaceView implements Runnable,
  SurfaceHolder.Callback {

 private Thread thread;
 SurfaceHolder holder;
 private boolean refreshFlg;
 private Bitmap bmp;

 public MySurfaceView(Context context) {
  super(context);

  refreshFlg = false;

  holder = getHolder();
  getHolder().addCallback(this);
  setFocusable(true);
  requestFocus();
 }

 @Override
 public void surfaceCreated(SurfaceHolder arg0) {

  // スレッドの作成と実行(run()の実行)
  thread = new Thread(this);
  thread.start();
 }

 // スレッドの削除
 public void StopThread() {
  thread = null;
 }

 @Override
 public void run() {
  // TODO 自動生成されたメソッド・スタブ
  // TODO:DEBUG
  Log.v("*TEST*", "MySurfaceView_RUN");

  long loopCount = 0;
  long waitTime = 0;
  long startTime = System.currentTimeMillis();

  while (thread != null) {
   loopCount++;
   try {
    if (refreshFlg == true) {
     draw();
     //refreshFlg = false;
    }
    waitTime = (loopCount * FRAME_TIME)
      - System.currentTimeMillis() - startTime;
    if (waitTime > 0) {
     Thread.sleep(waitTime);
    }
   } catch (Exception e) {
    Log.v("*TEST*", "MySurfaceView_RUN_ERR");
   }
 }
 }

 // 描画処理
 public void draw() {

  Paint paint = new Paint();

  Canvas canvas = holder.lockCanvas();
  canvas.drawBitmap(bmp, 0, 0, paint);
  holder.unlockCanvasAndPost(canvas);

 }
 
 //描画フラグ設定
 public void setRefreshFlg(boolean flg){
  refreshFlg = flg;
  return;
 }
 
 public Bitmap getOffScreenBmp(){
  return bmp;
 }

 public void setOffScreenBmp(Bitmap bitmap){
  bmp = bitmap;
 }
}

あかん、インデント直す気になれん・・・。
つーか、括弧の数あってるのか?

やってることは、
アクティビティでSurfaceViewを生成しスレッドを立てる。
これでsurfaceCreatedが呼ばれ、
スレッドが立てられることでrun()が実行される。
run()はスレッドが生きている間、
実際に描画を行うdraw()を日々出し続ける。

後は、アクティビティ側で
描画するビットマップをCanvasに貼りまくり、
定期的にMySurfaceView側のBitmapに渡せばいい。
ソースでは一度画面表示した後、
すぐに別の画像を作成して上書きを行っている。
速すぎて切り替わりを確認することはできないw

アクティビティ終了時にスレッドを削除するようにしている。
これをやらないとアプリ終了後もスレッドが
生き続けて気持ち悪かったので追加した。
放っておいても勝手に停止する・・・らしい?

コメントアウトしているけど、
refreshFlg で全てのアイテムを処理したか
判定して描画を制御する予定。

参考にさせて頂きました!(丸パク・・・)
http://android.keicode.com/basics/surfaceview-1.php


やっと4-3攻略しました!




最新の画像もっと見る

コメントを投稿