gpt4 book ai didi

java - Android AsyncTask 卡住了

转载 作者:行者123 更新时间:2023-11-29 08:55:31 29 4
gpt4 key购买 nike

上下文:Android 应用程序的以下 AsyncTask 从服务器发送和接收所谓的 Request 对象。如果用户在应用程序中更改了他的内容,则会生成新的请求对象并将其添加到同步队列中。如果他随后点击同步按钮,AsyncTask 将被创建并以他的请求作为参数执行。

处理程序最终获取所有答案并在数据库中设置必要的结果。然后,他最终通过在 UI 线程 (onPostExecute) 上调用一个方法来更新 UI。

public class RequestSender extends AsyncTask<Request, Void, Boolean>{

// Server data
private String host;
private int port = 1337;

private Socket socket;
private AnswerHandler handler;

public RequestSender(AnswerHandler handler) {
this.host = "hostNameHere";
this.handler = handler;
}

/**
* This method gets started as asynchronous task when you call .run()
* @return
*/
@Override
protected Boolean doInBackground(Request... requests) {
return sendAndReceive(requests);
}

private boolean sendAndReceive(Request... requests) {
boolean isConnected = this.initSocket();
if(isConnected) {
this.send(requests);
this.waitForAnswer();
} else {
handler.setRequests(requests);
}
return isConnected;
}

/**
* Tries to open a socket on the android device to a specified Host
*/
private boolean initSocket() {
try {
SocketAddress sockaddr = new InetSocketAddress(host, port);
socket = new Socket();
socket.connect(sockaddr, 5000);
return true;
} catch (UnknownHostException e) {
System.err.println("Unknown Host in initSocket()");
} catch (IOException e) {
System.err.println("Connection timed out");
}
return false;
}

/**
* Tries to send a request to the server
* @param request
*/

public void send(Request... request) {
if(socket != null) {
try {
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
out.writeObject(request);
out.flush();
} catch (IOException e) {
System.err.println("Couldn't write to socket in RequestSender");
}
}
}

/**
* Waits for the answer from the server and reports the result in the handler
*/
private void waitForAnswer() {
try {
socket.setSoTimeout(5000);
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
Request[] answers = (Request[]) in.readObject();
socket.close();
handler.setRequests(answers);
} catch (StreamCorruptedException e) {
System.err.println("Failed to open stream from server");
} catch (IOException e) {
System.err.println("Failed to read answers from server");
} catch (ClassNotFoundException e) {
System.err.println("Failed to read class from server");
}
}

@Override
protected void onPostExecute(Boolean a) {
handler.updateUI();
}

}

现在我的问题:整个过程几次都没有任何问题(这取决于我手机的善意多少次),但似乎任务卡在某个地方而没有给我任何关于 System.err 的错误消息。重新启动应用程序解决了问题,它再次运行没有任何问题。

我已经读到 AsyncTasks 从 Honeycomb 开始在一个线程上执行。我在打开的套接字上设置了超时并读入,因此卡住的任务应该在该超时后终止。

我的代码有什么问题吗?您能想出解决方案吗?

最佳答案

最近我遇到了这个问题,经过大量调试和头脑 Storm 一周后,我终于找到了这个错误。

好的,让我们做一些功课。

发送/接收数据的过程

  1. 建立联系。假设 connectToServer() 是一个将设备物理连接到服务器的函数。
  2. 套接字/TCP 部分。在您的情况下,您有 doInbackground(),您在其中调用 initSocket() 来启动套接字连接。

In real world scenario when you request a connection to a server it takes some time, may be a one or two seconds. So you should wait for that time before initiating a socket connection request. If a socket request send before a connection then it goes to lock state and releases after the default time out is finished which make it stuck.

编程场景

connectToServer();

// wait for 1 or 2 second.

initSocket();

示例代码

    /* Function to check whether we are physically connected to the server or not */
private boolean isConnEstablished(){
WifiInfo connInfo = mManager.getConnectionInfo();
return mManager.isWifiEnabled() && connInfo.getNetworkId() != -1 && connInfo.getIpAddress() != 0;
}

private void initSocket() {
boolean scanning = true;
int tryCount = 5; // we trying for 5 times

try {
while (scanning && tryCount > 0) {
try {
if (isConnEstablished()) {
try{
Thread.sleep(500);
}catch (InterruptedException e){
Log.e("Yo", "sleep-error");
}
tConnection = new Socket(host, port);
scanning = false;
Log.e(getClass().getName(), "Socket connection established");
}else {
throw new ConnectException();
}
} catch (ConnectException e) {
Log.e(getClass().getName(), "connecting again...");
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Log.e(getClass().getName(), "System sleep-error: " + ex.getMessage());
}
}
tryCount--;
}

}

关于java - Android AsyncTask 卡住了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20471418/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com