Java readUTF()导致Android应用程序挂起
我正试图在link上编译代码 代码不起作用,因为它挂起在这行上:Java readUTF()导致Android应用程序挂起,java,android,Java,Android,我正试图在link上编译代码 代码不起作用,因为它挂起在这行上: textIn.setText(dataInputStream.readUTF()); 出于某种原因,它不会挂在writeUTF上,而是挂在readUTF上 有人能给我指一下正确的方向吗 这是我的密码: public Socket socket = null; public DataOutputStream dataOutputStream = null; public DataInputStream dataInputStrea
textIn.setText(dataInputStream.readUTF());
出于某种原因,它不会挂在writeUTF上,而是挂在readUTF上
有人能给我指一下正确的方向吗
这是我的密码:
public Socket socket = null;
public DataOutputStream dataOutputStream = null;
public DataInputStream dataInputStream = null;
public Thread readjsonthrd = new Thread(new ReadJSONThread());
private final static String LOG_TAG = AndroidClient.class.getSimpleName();
private final Handler handler = new Handler();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.e(LOG_TAG, "Before OnCreate() Try");
try {
Log.e(LOG_TAG, "In OnCreate() Try");
socket = new Socket("23.23.175.213", 9000);
Log.e(LOG_TAG, "Created Socket");
dataOutputStream = new DataOutputStream(socket.getOutputStream());
Log.e(LOG_TAG, "Created DataOutputStream");
dataInputStream = new DataInputStream(socket.getInputStream());
Log.e(LOG_TAG, "Created DataInputStream");
Profile p = new Profile();
Log.e(LOG_TAG, "Created Profile Instance");
//Gets the local profile via JSON and converts into Profile type
Gson gson = new Gson();
Log.e(LOG_TAG, "Created Gson Instance");
p = gson.fromJson(p.getProfileJSONStr(), Profile.class);
Log.e(LOG_TAG, "Converted Profile to JSON");
//Gson gson = new Gson();
Log.e(LOG_TAG, "Before: outputJSON = gson.toJson(p);");
outputJSON = gson.toJson(p);
Log.e(LOG_TAG, "Created outputJSON");
dataOutputStream.writeUTF(outputJSON); //OUTPUT OF JSON FROM LOCAL PROFILE BEING SENT TO THE SERVER
dataOutputStream.flush();
Log.e(LOG_TAG, "Created dataOutputStream");
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.e(LOG_TAG, "Before initEventHandlers");
initEventHandlers();
Log.e(LOG_TAG, "Create Thread");
Thread serverthrd = new Thread(new ServerThread());
Log.e(LOG_TAG, "Start Thread");
serverthrd.start();
Log.e(LOG_TAG, "Started Thread");
}
public class ServerThread implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
//Socket socket = null;
//DataOutputStream dataOutputStream = null;
//DataInputStream dataInputStream = null;
Log.e(LOG_TAG, "Before Server Try Statement");
try {
Log.e(LOG_TAG, "In Server Try Statement");
//socket = new Socket("23.23.175.213", 1337);
//dataOutputStream = new DataOutputStream(socket.getOutputStream());
//dataInputStream = new DataInputStream(socket.getInputStream());
/*Profile p = null;
//Gets the local profile via JSON and converts into Profile type
Gson gson = new Gson();
p = gson.fromJson(p.getProfileJSONStr(), Profile.class);
//Gson gson = new Gson();
outputJSON = gson.toJson(p);
dataOutputStream.writeUTF(outputJSON); //OUTPUT OF JSON FROM LOCAL PROFILE BEING SENT TO THE SERVER
*/
//dataOutputStream.writeUTF(textOut.getText().toString()); //OUTPUT JSON GOES HERE
//textIn.setText(dataInputStream.readUTF());
Log.e(LOG_TAG, "Start Thread");
readjsonthrd.start();
Log.e(LOG_TAG, "Started Thread");
/*Log.e(LOG_TAG, "Before inputJSON String");
inputJSON = dataInputStream.readUTF();
//Convert
Log.e(LOG_TAG, "After inputJSON String");
Log.e(LOG_TAG, "InputJSON:" + inputJSON);*/
//textIn.setText(dataInputStream.readUTF()); //GET JSON COMING FROM SERVER HERE
refreshViewModels();
} /*catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
finally{
if (socket != null){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (dataOutputStream != null){
try {
dataOutputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (dataInputStream != null){
try {
dataInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
public class ReadJSONThread implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
//Socket socket = null;
//DataOutputStream dataOutputStream = null;
//DataInputStream dataInputStream = null;
Log.e(LOG_TAG, "Before Read JSON Try Statement");
try {
Log.e(LOG_TAG, "Before inputJSON String");
inputJSON = dataInputStream.readUTF();
//Convert
Log.e(LOG_TAG, "After inputJSON String");
}
catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
readUTF是一个阻塞网络调用。您应该从不是主UI线程的单独线程调用它,该示例就是这样做的。因为它是阻塞的,所以它将挂起当前线程,直到is接收到数据为止,因此您应该给它一个单独的线程
Android文档实际上特别推荐这样做,因为您将收到应用程序不响应错误,因为等待网络呼叫时间过长
编辑:根据您提供的代码,您只是设置了错误的线程。您希望在线程本身中创建套接字,也可以通过构造函数传递它。在线程中只使用readUTF方法不会有多大作用
我的建议是在ReadJSONThread类中创建一些称为write和read的包装器方法,然后在其中实现相应的套接字方法。然后在onCreate方法中创建Thread对象,当需要写入时,可以调用.write。对于读取,我会在read方法中创建一个循环,当它成功地从网络中读取时,让它从活动类调用一个方法来对数据执行处理。readUTF是一个阻塞网络调用。您应该从不是主UI线程的单独线程调用它,该示例就是这样做的。因为它是阻塞的,所以它将挂起当前线程,直到is接收到数据为止,因此您应该给它一个单独的线程
Android文档实际上特别推荐这样做,因为您将收到应用程序不响应错误,因为等待网络呼叫时间过长
编辑:根据您提供的代码,您只是设置了错误的线程。您希望在线程本身中创建套接字,也可以通过构造函数传递它。在线程中只使用readUTF方法不会有多大作用
我的建议是在ReadJSONThread类中创建一些称为write和read的包装器方法,然后在其中实现相应的套接字方法。然后在onCreate方法中创建Thread对象,当需要写入时,可以调用.write。对于读取,我会在read方法中创建一个循环,当它成功地从网络中读取数据时,让它调用活动类中的一个方法来对数据执行处理。readUTF是特定于java的:首先读取两个字节并将其用作长度,然后读取字节并将其视为修改过的UTF-8。基本上,要使其工作,您需要一个使用writeUTF的java服务器
另外,您不应该在UI线程上运行长时间运行的操作=网络调用。这将阻止UI重画和事件处理,因此您的应用程序将显示为挂起。用于在后台线程上运行长时间运行的任务。readUTF是特定于java的:首先读取两个字节并将其用作长度,然后读取字节并将其视为修改过的UTF-8。基本上,要使其工作,您需要一个使用writeUTF的java服务器
另外,您不应该在UI线程上运行长时间运行的操作=网络调用。这将阻止UI重画和事件处理,因此您的应用程序将显示为挂起。用于在后台线程上运行长时间运行的任务。而不是
读取器
如果你
阅读线
假设您的服务器发送了一条或两条正确终止的线路作为答案,那么您应该摆脱这些问题
注意:如果您在主活动中运行此功能,从ICS开始,您将遇到在主线程中打开网络连接的限制问题。如果您选择不禁用限制,一个快速解决方案是asynctask,它可能不允许您访问主布局和文本视图 而不是
读取器
如果你
阅读线
假设您的服务器发送了一条或两条正确终止的线路作为答案,那么您应该摆脱这些问题
注意:如果您在主活动中运行此功能,从ICS开始,您将遇到在主线程中打开网络连接的限制问题。如果您选择不禁用限制,一个快速解决方案是asynctask,它可能不允许您访问主布局和文本视图 在与一个gov API集成时,我遇到了一些类似的问题,当时我使用的是readUTF writeUTF,每次在readUTF上都没有任何响应 我发现服务器是用c语言编写的,并且需要以*结尾或请求字符串,响应也以*结尾 我解决了这个问题,直接在套接字的输入/输出流上写入,并在遇到**时终止读取
Socket client = new Socket(serverIp, port);
OutputStream out = client.getOutputStream();
InputStream in = client.getInputStream();
String test = "REQUEST-STRING**";
out.write(test.getBytes());
out.flush();
int c;
while ((c=in.read())!=-1) {
if (isEndOfResponse(c)) {
break;
}
System.out.print((char)c);
}
client.close();
在与集成时,我遇到了一些类似的问题 在一个GovAPI中,我使用的是readUTF-writeUTF,每次在readUTF上都没有任何响应 我发现服务器是用c语言编写的,并且需要以*结尾或请求字符串,响应也以*结尾 我解决了这个问题,直接在套接字的输入/输出流上写入,并在遇到**时终止读取
Socket client = new Socket(serverIp, port);
OutputStream out = client.getOutputStream();
InputStream in = client.getInputStream();
String test = "REQUEST-STRING**";
out.write(test.getBytes());
out.flush();
int c;
while ((c=in.read())!=-1) {
if (isEndOfResponse(c)) {
break;
}
System.out.print((char)c);
}
client.close();
您可以使用线程:
public static DataInputStream dis;
//...
Thread thread = new Thread() {
@Override
public void run() {
while (Connected) {
String msg = null;
try {
if(dis==null)break;
msg = dis.readLine();
Log.i("TAG", "dataRecived: "+msg);
} catch (IOException e) {
e.printStackTrace();
}
}
Log.i("TAG", "Reciver END");
}
};
thread.start();
因此,在使用readLine或readUTF时,您的应用程序不会挂起。您可以使用线程:
public static DataInputStream dis;
//...
Thread thread = new Thread() {
@Override
public void run() {
while (Connected) {
String msg = null;
try {
if(dis==null)break;
msg = dis.readLine();
Log.i("TAG", "dataRecived: "+msg);
} catch (IOException e) {
e.printStackTrace();
}
}
Log.i("TAG", "Reciver END");
}
};
thread.start();
因此,在使用readLine或readUTF时,您的应用程序不会挂起。您是否使用writeUTF发送数据?这是唯一一个可以生成readUTF可以理解的东西的API。您是否使用writeUTF发送数据?这是唯一一个能够产生readUTF能够理解的东西的API。