尽管使用了AsyncTask

时间:2015-07-25 21:16:48

标签: java android sockets android-asynctask

重复:请注意我已经确认了其他Q& As(线程用户界面)但我的情况有所不同,因为我尝试使用该解决方案,但它并不适用于所有情况(因为它有效)写作但不适合阅读。

更新:我确切地知道出了什么问题,请阅读大胆的我的问题部分 我试图制作一个通过WiFi连接到Java服务器的Android套接字客户端。最终客户端将发送和接收命令和日志,因为有一个文本框,用户可以在其中编写SQL命令并点击按钮命令将从应用程序发送到桌面服务器,并在另一个文本框中显示日志。

到目前为止,我一直在尝试使用其他问题的This Answer制作该客户端,并在TCP客户端中添加以下行。

Scanner  in = new Scanner(socket.getInputStream());//in doInBackground
//also changed send method a little
public String send(String command)
{
    if ( connected ){
        out.println(command);
        out.flush();

        String back = in.nextLine().toString();
        return back;

    }
    return "not Connected";
}

连接成功完成,send方法在服务器收到命令时发送命令。但是服务器写回的字符串会在标题中抛出提到的异常,尽管我使用的是AsyncTask。

我的问题

为什么在PrintWriter正常工作时Scanner会抛出此异常?

主要活动

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends ActionBarActivity {


EditText serverIP, servMsg;
String ip, serverOut;
Button connectBtn;
TcpClient tcpClient;

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

    serverIP = (EditText) findViewById(R.id.serverIP);
    connectBtn = (Button) findViewById(R.id.connectBtn);
    servMsg = (EditText) findViewById(R.id.servMsg);

}

public void onConnectBtn(View view){

    try{

        ip = serverIP.getText().toString();
        tcpClient = new TcpClient();
        tcpClient.connect(getApplicationContext(), ip, 8082);
        serverOut = tcpClient.send("HELLO FROM cat:123");
        servMsg.setText(serverOut);

        tcpClient.disconnect(getApplicationContext());

    }
    catch (Exception e){

        Toast.makeText(getApplicationContext(),
                "Exception on runnning thread: " + e.getMessage().toString(), Toast.LENGTH_LONG).show();

    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
  }
}

TCP客户端

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Handler;
import android.util.Log;
import android.widget.Toast;

public class TcpClient {

private static final String TAG = TcpClient.class.getSimpleName();

private Socket socket;
private PrintWriter out;
private Scanner in;
private boolean connected;

public TcpClient() {
    socket = null;
    out = null;
    connected = false;
}


public void connect(Context context, String host, int port) {
    new ConnectTask(context).execute(host, String.valueOf(port));
}

private class ConnectTask extends AsyncTask<String, Void, Void> {

    private Context context;

    public ConnectTask(Context context) {
        this.context = context;
    }

    @Override
    protected void onPreExecute() {
        showToast(context, "Connecting..");
        super.onPreExecute();
    }

    @Override
    protected void onPostExecute(Void result) {
        if (connected) {
            showToast(context, "Connection successful");
        }
        super.onPostExecute(result);
    }

    private String host;
    private int port;

    @Override
    protected Void doInBackground(String... params) {
        try {
            String host = params[0];
            int port = Integer.parseInt(params[1]);
            socket = new Socket(host, port);
            out = new PrintWriter(socket.getOutputStream(), true);
            in = new Scanner(socket.getInputStream());
        } catch (UnknownHostException e) {
            showToast(context, "Don't know about host: " + host + ":" + port);
            Log.e(TAG, e.getMessage());
        } catch (IOException e) {
            showToast(context, "Couldn't get I/O for the connection to: " + host + ":" + port);
            Log.e(TAG, e.getMessage());
        }
        connected = true;
        return null;
    }


}

public void disconnect(Context context) {
    if (connected) {
        try {
            out.close();
            socket.close();
            connected = false;
        } catch (IOException e) {
            showToast(context, "Couldn't get I/O for the connection");
            Log.e(TAG, e.getMessage());
        }
    }
}


/**
 * Send command to a Pure Data audio engine.
 */
 public String send(String command)
{
    if ( connected ){
        out.println(command);
        out.flush();

        String back = in.nextLine().toString();
        return back;

    }
    return "not Connected";
}
private void showToast(final Context context, final String message) {
    new Handler(context.getMainLooper()).post(new Runnable() {

        @Override
        public void run() {
            Toast.makeText(context, message, Toast.LENGTH_LONG).show();
        }
    });
  }
}

此外Layout现在包含两个TextEdits,其中用户键入计算机的IP(我使用正确的IP检查),第二个将显示服务器响应。

1 个答案:

答案 0 :(得分:0)

我相信你不是&#34;刷新&#34;,这实质上是迫使缓冲区清空其内容。请看一下使用TCP / IP的这个工作聊天服务器/客户端代码。另外,我建议不要扩展ActionBarActivity,因为它已被弃用(谷歌表示他们将远离它并且很快就会支持它)。请参阅第3个链接。

ChatServer.java

ChatClient.java

ActionBar Activity deprecation