2013年2月8日 星期五

Handler + Thread implement

最近嘗試利用 Handler + Thread 去處理 App 較花時間的部分,否則 App 會出現 ANR(Application Not Resopnding)。

所以我藉由 Handler + Thread 實作了一個簡單的主題 - OOXX,下列呈現相關的部分程式碼。



黃色部分,為呼叫一個新的 Thread 去處理該事情。
BlockBtn[0].setOnClickListener(new ImageButton.OnClickListener() {



   @Override

   public void onClick(View v) {

    // TODO Auto-generated method stub

    if (round % 2 == 1) {

     BlockBtn[0].setBackgroundResource(R.drawable.cross_block);

     BlockFlag[0] = 2;

    } else {

     BlockBtn[0].setBackgroundResource(R.drawable.circle_block);

     BlockFlag[0] = 1;

    }

    round++;

    RoundEt.setText(Integer.toString(round / 2 + 1));

    BlockBtn[0].setEnabled(false);

    if (round >= 5)

     new Thread(new CheckResultThread(BlockFlag,

       ResultMsgHandler)).start();

   }

  });
這為該 Thread 處理的事情,並且透過 Handler 傳 Message 。
public void run() {
  // TODO Auto-generated method stub
  if (BlockFlag[0] != 0 && BlockFlag[0] == BlockFlag[1]
    && BlockFlag[1] == BlockFlag[2]) {
   Message msg = this.ResultMsgHandler.obtainMessage();
   if (BlockFlag[0] == 1)
    msg.getData().putString("Result", "1player");
   else
    msg.getData().putString("Result", "2player");
   this.ResultMsgHandler.sendMessage(msg);
  } else if (BlockFlag[3] != 0 && BlockFlag[3] == BlockFlag[4]
    && BlockFlag[4] == BlockFlag[5]) {
   Message msg = this.ResultMsgHandler.obtainMessage();
   if (BlockFlag[3] == 1)
    msg.getData().putString("Result", "1player");
   else
    msg.getData().putString("Result", "2player");
   this.ResultMsgHandler.sendMessage(msg);
  } else if (BlockFlag[6] != 0 && BlockFlag[6] == BlockFlag[7]
    && BlockFlag[7] == BlockFlag[8]) {
   Message msg = this.ResultMsgHandler.obtainMessage();
   if (BlockFlag[6] == 1)
    msg.getData().putString("Result", "1player");
   else
    msg.getData().putString("Result", "2player");
   this.ResultMsgHandler.sendMessage(msg);
  } else if (BlockFlag[0] != 0 && BlockFlag[0] == BlockFlag[3]
    && BlockFlag[3] == BlockFlag[6]) {
   Message msg = this.ResultMsgHandler.obtainMessage();
   if (BlockFlag[0] == 1)
    msg.getData().putString("Result", "1player");
   else
    msg.getData().putString("Result", "2player");
   this.ResultMsgHandler.sendMessage(msg);
  } else if (BlockFlag[1] != 0 && BlockFlag[1] == BlockFlag[4]
    && BlockFlag[4] == BlockFlag[7]) {
   Message msg = this.ResultMsgHandler.obtainMessage();
   if (BlockFlag[1] == 1)
    msg.getData().putString("Result", "1player");
   else
    msg.getData().putString("Result", "2player");
   this.ResultMsgHandler.sendMessage(msg);
  } else if (BlockFlag[2] != 0 && BlockFlag[2] == BlockFlag[5]
    && BlockFlag[5] == BlockFlag[8]) {
   Message msg = this.ResultMsgHandler.obtainMessage();
   if (BlockFlag[2] == 1)
    msg.getData().putString("Result", "1player");
   else
    msg.getData().putString("Result", "2player");
   this.ResultMsgHandler.sendMessage(msg);
  } else if (BlockFlag[0] != 0 && BlockFlag[0] == BlockFlag[4]
    && BlockFlag[4] == BlockFlag[8]) {
   Message msg = this.ResultMsgHandler.obtainMessage();
   if (BlockFlag[0] == 1)
    msg.getData().putString("Result", "1player");
   else
    msg.getData().putString("Result", "2player");
   this.ResultMsgHandler.sendMessage(msg);
  } else if (BlockFlag[2] != 0 && BlockFlag[2] == BlockFlag[4]
    && BlockFlag[4] == BlockFlag[6]) {
   Message msg = this.ResultMsgHandler.obtainMessage();
   if (BlockFlag[2] == 1)
    msg.getData().putString("Result", "1player");
   else
    msg.getData().putString("Result", "2player");
   this.ResultMsgHandler.sendMessage(msg);
  }
  else {
   Message msg = this.ResultMsgHandler.obtainMessage();
   msg.getData().putString("Result", "Non");
   this.ResultMsgHandler.sendMessage(msg);
  }
 }
當 Handler 接到 Message 之後,將透過分析 Message 執行相對應的動作。
Handler ResultMsgHandler = new Handler() {

  @Override
  public void handleMessage(Message msg) {
   // TODO Auto-generated method stub
   super.handleMessage(msg);
   String m = msg.getData().getString("Result");
   if (m.equals("Non")) {
    if (round < 9)
     return;
    else
     Toast.makeText(TwoPlayerMode.this, "Come out even!",
       Toast.LENGTH_LONG).show();
   } else {
    if (round % 2 == 1)
     Toast.makeText(TwoPlayerMode.this,
       OnePlayerModeEt.getText().toString() + " Win!",
       Toast.LENGTH_LONG).show();
    else
     Toast.makeText(TwoPlayerMode.this,
       TwoPlayerModeEt.getText().toString() + " Win!",
       Toast.LENGTH_LONG).show();
   }
   intent = new Intent();
   intent.setClass(TwoPlayerMode.this, MainActivity.class);
   startActivity(intent);
   TwoPlayerMode.this.finish();
  }
 };
參考資料:
Android Handler 筆記
Android AsyncTask 與 Handler Thread 的差異
android之handler使用
Android异步处理系列文章索引
Android消息队列模型——Thread,Handler,Looper,Massage Queue

沒有留言:

張貼留言