Android 调用 class 使用新线程连接到服务器时,应用程序崩溃
Android app crashes when class is called that uses a new thread to connect to server
这是有问题的 class
public class ServerLink {
private static Context context;
private Socket sock;
private String IP;
private int Port;
private InputStream is;
private OutputStream out;
private String temp;
private boolean bTemp;
public ServerLink(Context contxt){
this(contxt,"18.220.103.72",2267);
}
public ServerLink(Context contxt,String inIP, int inPort){
context = contxt;
IP = inIP;
Port = inPort;
}
public boolean sendLoginToServer(final String pass, final String username){
Thread t1 = new Thread(new Runnable() {
public void run()
{
try{
bTemp = false;
sock = new Socket(IP,Port);
out = sock.getOutputStream();
is = sock.getInputStream();
sendToServer("Login");
sendToServer(username.length() + ";" + username + ";" + pass);
temp = "";
String serverAnswer = Listener();
if(serverAnswer.equals("")){
Toast.makeText(context,"WTF",Toast.LENGTH_LONG).show();
}
else if(serverAnswer.equals("login")){
Toast.makeText(context,"Yay",Toast.LENGTH_LONG).show();
bTemp = true;
}
else if(serverAnswer.equals("nigol")){
Toast.makeText(context,"Nay",Toast.LENGTH_LONG).show();
}
}
catch (java.io.IOException e){
Toast.makeText(context,e.getMessage().toString(),Toast.LENGTH_LONG).show();
}
}});
t1.start();
return bTemp;
}
public void sendToServer(String input){
try{
String toSend = input;
byte[] toSendBytes = toSend.getBytes();
int toSendLen = toSendBytes.length;
byte[] toSendLenBytes = new byte[4];
toSendLenBytes[0] = (byte)(toSendLen & 0xff);
toSendLenBytes[1] = (byte)((toSendLen >> 8) & 0xff);
toSendLenBytes[2] = (byte)((toSendLen >> 16) & 0xff);
toSendLenBytes[3] = (byte)((toSendLen >> 24) & 0xff);
out.write(toSendLenBytes);
out.write(toSendBytes);
}
catch (java.io.IOException e){
Toast.makeText(context,e.getMessage().toString(),Toast.LENGTH_LONG).show();
}
}
public String Listener(){
try {
byte[] lenBytes = new byte[4];
is.read(lenBytes, 0, 4);
int len = (((lenBytes[3] & 0xff) << 24) | ((lenBytes[2] & 0xff) << 16) |
((lenBytes[1] & 0xff) << 8) | (lenBytes[0] & 0xff));
byte[] receivedBytes = new byte[len];
is.read(receivedBytes, 0, len);
String message = new String(receivedBytes, 0, len);
return message;
}
catch (java.io.IOException e){
Toast.makeText(context,e.getMessage().toString(),Toast.LENGTH_LONG).show();
return e.getMessage().toString();
}
}
}
它在调用时使我的应用程序崩溃。我尝试为每个人使用一个新线程,这段代码确实有效,我尝试将它用作方法,但它是一个小组项目,所以我想要一个 class 每个人都可以轻松使用,但目前不起作用.它应该连接到一个服务器 returns 如果成功登录,如果不成功则 nigol,服务器可以工作,我们已经在其他平台上测试过它,但我似乎无法class 正确[=13] =]
您无法显示来自 UI 以外的任何线程的 toast 消息。我建议使用 AsyncTask 或使用这个:
MyActivity.this.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(activity, "Hello", Toast.LENGTH_SHORT).show();
}
});
这是有问题的 class
public class ServerLink {
private static Context context;
private Socket sock;
private String IP;
private int Port;
private InputStream is;
private OutputStream out;
private String temp;
private boolean bTemp;
public ServerLink(Context contxt){
this(contxt,"18.220.103.72",2267);
}
public ServerLink(Context contxt,String inIP, int inPort){
context = contxt;
IP = inIP;
Port = inPort;
}
public boolean sendLoginToServer(final String pass, final String username){
Thread t1 = new Thread(new Runnable() {
public void run()
{
try{
bTemp = false;
sock = new Socket(IP,Port);
out = sock.getOutputStream();
is = sock.getInputStream();
sendToServer("Login");
sendToServer(username.length() + ";" + username + ";" + pass);
temp = "";
String serverAnswer = Listener();
if(serverAnswer.equals("")){
Toast.makeText(context,"WTF",Toast.LENGTH_LONG).show();
}
else if(serverAnswer.equals("login")){
Toast.makeText(context,"Yay",Toast.LENGTH_LONG).show();
bTemp = true;
}
else if(serverAnswer.equals("nigol")){
Toast.makeText(context,"Nay",Toast.LENGTH_LONG).show();
}
}
catch (java.io.IOException e){
Toast.makeText(context,e.getMessage().toString(),Toast.LENGTH_LONG).show();
}
}});
t1.start();
return bTemp;
}
public void sendToServer(String input){
try{
String toSend = input;
byte[] toSendBytes = toSend.getBytes();
int toSendLen = toSendBytes.length;
byte[] toSendLenBytes = new byte[4];
toSendLenBytes[0] = (byte)(toSendLen & 0xff);
toSendLenBytes[1] = (byte)((toSendLen >> 8) & 0xff);
toSendLenBytes[2] = (byte)((toSendLen >> 16) & 0xff);
toSendLenBytes[3] = (byte)((toSendLen >> 24) & 0xff);
out.write(toSendLenBytes);
out.write(toSendBytes);
}
catch (java.io.IOException e){
Toast.makeText(context,e.getMessage().toString(),Toast.LENGTH_LONG).show();
}
}
public String Listener(){
try {
byte[] lenBytes = new byte[4];
is.read(lenBytes, 0, 4);
int len = (((lenBytes[3] & 0xff) << 24) | ((lenBytes[2] & 0xff) << 16) |
((lenBytes[1] & 0xff) << 8) | (lenBytes[0] & 0xff));
byte[] receivedBytes = new byte[len];
is.read(receivedBytes, 0, len);
String message = new String(receivedBytes, 0, len);
return message;
}
catch (java.io.IOException e){
Toast.makeText(context,e.getMessage().toString(),Toast.LENGTH_LONG).show();
return e.getMessage().toString();
}
}
}
它在调用时使我的应用程序崩溃。我尝试为每个人使用一个新线程,这段代码确实有效,我尝试将它用作方法,但它是一个小组项目,所以我想要一个 class 每个人都可以轻松使用,但目前不起作用.它应该连接到一个服务器 returns 如果成功登录,如果不成功则 nigol,服务器可以工作,我们已经在其他平台上测试过它,但我似乎无法class 正确[=13] =]
您无法显示来自 UI 以外的任何线程的 toast 消息。我建议使用 AsyncTask 或使用这个:
MyActivity.this.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(activity, "Hello", Toast.LENGTH_SHORT).show();
}
});