Java Android TCP/IP和GUI与其他线程通信-Tic Tac Toe多人游戏
这就是交易。我想用Android实现多人游戏Tic-Tac-Toe。我使用Java部署了多线程服务器,但在客户端上遇到了麻烦。据我所知,您应该使用后台线程来处理通信,而将UI线程留给UI处理。我在开发游戏循环和线程通信时遇到了一些问题。我决定使用处理程序而不是异步任务 我认为循环应该在后台线程中实现,看起来有点像这样: 使用处理程序从UI获取信息 将数据写入服务器的输出流 从服务器的输入流中读取数据 处理数据 使用其他处理程序将数据发送到UI 我正在使用Eclipse和仿真器作为客户机进行测试。问题是我无法设置处理程序。一个处理程序UIHandler作为参数发送给ClientThread构造函数,而Net处理程序则通过一个方法从客户端线程获取到UIThread 我读到我需要使用活套来处理传入的数据。我不能在一个无休止的循环中调用handleMessage方法吗?我真的不知道如何部署这个。我很乐意接受任何意见 主要活动客户端类:Java Android TCP/IP和GUI与其他线程通信-Tic Tac Toe多人游戏,java,android,multithreading,tcp,handler,Java,Android,Multithreading,Tcp,Handler,这就是交易。我想用Android实现多人游戏Tic-Tac-Toe。我使用Java部署了多线程服务器,但在客户端上遇到了麻烦。据我所知,您应该使用后台线程来处理通信,而将UI线程留给UI处理。我在开发游戏循环和线程通信时遇到了一些问题。我决定使用处理程序而不是异步任务 我认为循环应该在后台线程中实现,看起来有点像这样: 使用处理程序从UI获取信息 将数据写入服务器的输出流 从服务器的输入流中读取数据 处理数据 使用其他处理程序将数据发送到UI 我正在使用Eclipse和仿真器作为客户机进行测试。
package com.example.tictactoecliet;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.StrictMode;
import android.os.StrictMode.ThreadPolicy;
import android.util.Log;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.RadioButton;
import android.widget.TextView;
import android.widget.ViewFlipper;
public class MainActivity extends Activity implements OnClickListener,
ClientVocabulary {
private static final String TAG = MainActivity.class.getSimpleName();
private Socket client;
private PrintWriter pw;
private EditText etIp;
private TextView tvStatus;
private Button bCon;
private Socket socket;
PrintWriter out;
private BufferedReader in;
private RadioButton rbVsPlayer, rbVsAI;
private ViewFlipper vF;
private ClientThread cT;
private ImageButton[][] board = new ImageButton[5][5];
private Handler h, clientHandler;
SocketAddress sockaddr;
/******************************************************************************************/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
setupUIHandler();
try {
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*****************************************
* initialize
*
* @return nothing ffs
******************************************/
private void init() {
etIp = (EditText) findViewById(R.id.etIP);
tvStatus = (TextView) findViewById(R.id.tvStatus);
rbVsAI = (RadioButton) findViewById(R.id.rbAI);
rbVsPlayer = (RadioButton) findViewById(R.id.rb2players);
bCon = (Button) findViewById(R.id.bCon);
//
// // listeners
//
vF = (ViewFlipper) findViewById(R.id.vF);
bCon.setOnClickListener(this);
board[0][0] = (ImageButton) findViewById(R.id.iB_1A);
board[0][1] = (ImageButton) findViewById(R.id.iB_2A);
board[0][2] = (ImageButton) findViewById(R.id.iB_3A);
board[0][3] = (ImageButton) findViewById(R.id.iB_4A);
board[0][4] = (ImageButton) findViewById(R.id.iB_5A);
board[1][0] = (ImageButton) findViewById(R.id.iB_1B);
board[1][1] = (ImageButton) findViewById(R.id.iB_2B);
board[1][2] = (ImageButton) findViewById(R.id.iB_3B);
board[1][3] = (ImageButton) findViewById(R.id.iB_4B);
board[1][4] = (ImageButton) findViewById(R.id.iB_5B);
board[2][0] = (ImageButton) findViewById(R.id.iB_1C);
board[2][1] = (ImageButton) findViewById(R.id.iB_2C);
board[2][2] = (ImageButton) findViewById(R.id.iB_3C);
board[2][3] = (ImageButton) findViewById(R.id.iB_4C);
board[2][4] = (ImageButton) findViewById(R.id.iB_5C);
board[3][0] = (ImageButton) findViewById(R.id.iB_1D);
board[3][1] = (ImageButton) findViewById(R.id.iB_2D);
board[3][2] = (ImageButton) findViewById(R.id.iB_3D);
board[3][3] = (ImageButton) findViewById(R.id.iB_4D);
board[3][4] = (ImageButton) findViewById(R.id.iB_5D);
board[4][0] = (ImageButton) findViewById(R.id.iB_1E);
board[4][1] = (ImageButton) findViewById(R.id.iB_2E);
board[4][2] = (ImageButton) findViewById(R.id.iB_3E);
board[4][3] = (ImageButton) findViewById(R.id.iB_4E);
board[4][4] = (ImageButton) findViewById(R.id.iB_5E);
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
board[i][j].setOnClickListener(this);
}// end of inner for
}// end of outer for
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case (R.id.bCon):
vF.showNext();
blockAllTile();
cT = new ClientThread((short) (rbVsPlayer.isChecked() ? 2:1), clientHandler, etIp.getText().toString());
cT.start();
break;
case (R.id.iB_1A):
sendLocation(0);
break;
case (R.id.iB_2A):
sendLocation(1);
break;
case (R.id.iB_3A):
sendLocation(2);
break;
case (R.id.iB_4A):
sendLocation(3);
break;
case (R.id.iB_5A):
sendLocation(4);
break;
case (R.id.iB_1B):
sendLocation(5);
break;
case (R.id.iB_2B):
sendLocation(6);
break;
case (R.id.iB_3B):
sendLocation(7);
break;
case (R.id.iB_4B):
sendLocation(8);
break;
case (R.id.iB_5B):
sendLocation(9);
break;
case (R.id.iB_1C):
sendLocation(10);
break;
case (R.id.iB_2C):
sendLocation(11);
break;
case (R.id.iB_3C):
sendLocation(12);
break;
case (R.id.iB_4C):
sendLocation(13);
break;
case (R.id.iB_5C):
sendLocation(14);
break;
case (R.id.iB_1D):
sendLocation(15);
break;
case (R.id.iB_2D):
sendLocation(16);
break;
case (R.id.iB_3D):
sendLocation(17);
break;
case (R.id.iB_4D):
sendLocation(18);
break;
case (R.id.iB_5D):
sendLocation(19);
break;
case (R.id.iB_1E):
sendLocation(20);
break;
case (R.id.iB_2E):
sendLocation(21);
break;
case (R.id.iB_3E):
sendLocation(22);
break;
case (R.id.iB_4E):
sendLocation(23);
break;
case (R.id.iB_5E):
sendLocation(24);
break;
}
}
public void unblockAllTile(){
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
board[i][j].setEnabled(true);
}// end of inner for
}//
}
public void sendLocation(int location){
}
public void blockAllTile(){
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
board[i][j].setEnabled(false);
}// end of inner for
}// end of outer for
}
private void setupUIHandler(){
h = new Handler(){
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
Bundle b = msg.getData();
String content = b.getString("msg");
if(content.equals(KKIP_ALL_CONNECTED)){
tvStatus.setText(KKIP_ALL_CONNECTED);
}else{
Log.i("i no noł", "i no noł");
}
}
};
}
}
代码尚未完成,因此某些方法可能看起来很奇怪。我对解决UIThread到BackGroundThread到服务器的通信很感兴趣。没有其他内容。
处理程序
对象隐式绑定到创建它们的线程内运行的循环器
。您的后台线程需要创建自己的活套
(或者使用HandlerThread
为您处理活套
),然后您的后台线程需要将其处理程序
传回主UI线程
package com.example.tictactoecliet;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
public class ClientThread extends Thread implements ClientVocabulary {
private Socket socket;
private short game_mode;
private Handler uiHandler;
private Handler netHandler;
private Bundle inMsgBundle, outMsgBundle;
private final static String TAG = ClientThread.class.getSimpleName();
private BufferedReader in;
private String ip, serverResponse;
PrintWriter out;
public ClientThread(Short game_mode, Handler h, String ip) {
this.game_mode = game_mode;
this.uiHandler = h;
this.ip = ip;
inMsgBundle = new Bundle();
outMsgBundle = new Bundle();
}
@Override
public void run() {
// TODO Auto-generated method stub
Log.i("Thread started",TAG);
connectionSetup();
Log.i("Setup connection",TAG);
Looper.prepare();
setupHandler();
Log.i("Handler set",TAG);
try {
play();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Looper.loop();
}// end of run
public Handler getHandlerToMsgQueue() {
while (netHandler == null) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return netHandler;
}
// //////////////////////////////////////////
public void connectionSetup() {
try {
Log.i("Setup start",TAG);
InetAddress serverAddress = InetAddress.getByName(ip);
SocketAddress sockaddr = new InetSocketAddress(serverAddress, 4321);
// socket = new Socket("192.168.0.102",4321);
socket = new Socket();
socket.connect(sockaddr);
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
socket.getOutputStream())), true);
out.println(game_mode);
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
Log.i("Setup finish",TAG);
} catch (Exception e) {
e.printStackTrace();
}
}
////////////////
public void setupHandler(){
Log.i("Handler ready",TAG);
netHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
notifyAll();
}
};
Log.i("Handler done",TAG);
}
///////////////////////////play//////////////////////////
public void play() throws Exception{
String response;
Log.v("Play start", "Play start");
try {
response =null;
if(in.readLine()!=null){
response=in.readLine();
Log.v(response, response);
}else{
Log.v(TAG, "Resposne is empty");
}
if( response.startsWith(KKIP_WELCOME)){
Log.i("wow welcome so much", "so much welcome");
char mark = response.charAt(8);
}else if (response.startsWith(KKIP_WAITING_FOR_OPPONENT)){
while (true){
//updatuj status zegarem, może wait i notify?
if(response.startsWith(KKIP_ALL_CONNECTED)){
Log.v("now we play","play");
sendMessageToUI(KKIP_ALL_CONNECTED);
response=in.readLine();
if(response.startsWith(KKIP_VALID_MOVE)){
//update board
}else if (response.startsWith(KKIP_MOVED)){
int loc = Integer.parseInt(response.substring(15));
//update board
}else if (response.startsWith(KKIP_VICTORY)){
}else if(response.startsWith(KKIP_DEFEAT)){
}else if (response.startsWith(KKIP_TIE)){
}
}
}//end of while (true)
//end of if connected
}
out.print(KKIP_QUIT);
}
catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
finally{
socket.close();
}
}
private void sendMessageToUI(String msg){
Bundle data = new Bundle();
data.putString("msg", msg);
Message m = new Message();
m.setData(data);
uiHandler.sendMessage(m);
}
}