【发布时间】:2015-07-25 21:16:48
【问题描述】:
关于重复:请注意,我已经确认了其他问答(线程 UI),但我的情况不同,因为我尝试使用该解决方案,但它在所有情况下都不起作用(因为它适用于写作,但不适用于不是为了阅读。
更新:我确切地知道出了什么问题,请阅读粗体的我的问题部分 我正在尝试制作一个通过 WiFi 连接到 Java 服务器的 Android Socket 客户端。最终客户端将发送和接收命令和日志,因为将有一个文本框,用户可以在其中编写 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。
我的问题
为什么 Scanner 会在 PrintWriter 正常工作时抛出此异常?
主要活动
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 检查),第二个将显示服务器响应。
【问题讨论】:
-
“但我的情况不同,因为我尝试使用该解决方案但它不起作用” - 这可能是因为您不了解解决方案并且您申请了它不正确。回复:您认为输出有效的理论,您向我们展示了支持这一点的零证据。 (提示:堆栈跟踪...)
-
@StephenC 我不明白你的意思。这不是我的理论。正如我所说,我已经运行并调试了程序。它运行 write 方法,并且也在运行(不是理论上但实际上)的服务器接收消息。但在此之后,将执行 readline 方法,该方法会引发异常
标签: java android sockets android-asynctask