我使用此代码在两个设备之间传输数据。
public void run() {
try {
Socket s = new Socket(myIpAddress, SERVERPORT);
// outgoing stream redirect to socket
OutputStream out = s.getOutputStream();
PrintWriter output = new PrintWriter(out);
output.println("DLS");
BufferedReader input = new BufferedReader(new InputStreamReader(
s.getInputStream()));
// read line(s)
String st = input.readLine();
// . . .
// Close connection
s.close();
} catch (UnknownHostException e) {
run();
e.printStackTrace();
} catch (IOException e) {
run();
e.printStackTrace();
}
}
我的问题是我必须首先启动服务器,之后,我可以启动客户端以成功连接。
在
中public void run()
我将run()
添加到UnknownHostException
和IOException
。
它在其他代码中工作正常,但在这里我得到了StackOverFlowError
。
我怎样才能让它在有限的数量上重试并且每隔X秒尝试一次?
我尝试过这种方式,因为run()
和Thread.sleep(5000);
因未处理的异常而哭泣。当我启动该服务时,该应用程序被冻结。
public void run() throws UnknownHostException, IOException {
Socket s = new Socket(myIpAddress, SERVERPORT);
// outgoing stream redirect to socket
OutputStream out = s.getOutputStream();
PrintWriter output = new PrintWriter(out);
output.println("DLS");
s.close();
}
@Override
public void onCreate() {
for (int i = 0; i < 10; i++) {
try {
run();
break; // no exception: break out of the loop.
}
catch (IOException e) {
try {
Thread.sleep(5000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
答案 0 :(得分:0)
在catch中调用run()之前,你可以这样做 -
Thread.sleep(1000); // 1000 milli second = 1 second
这将使线程在再次调用run之前休眠一秒钟。此外,你不应该永远尝试,因为这会导致错误的递归调用,并且堆栈中没有足够的空间可以继续执行任何更多的代码执行,包括打印错误。也许你应该尝试最多5到10次,间隔3秒,然后放弃。
当没有虚拟内存可供执行时,会发生堆栈溢出错误。
假设您从创建方法调用运行 -
private static final int MAX_TRY = 5;
public void create(){
for(int i = 0; i < MAX_TRY; i++){
if(run()){ // if run call returns true, then get out of the loop
break;
} else {
Thread.sleep(1000); // Wait for a second before next try
}
}
}
public boolean run() {
boolean isSuccessful = false;
try {
Socket s = new Socket(myIpAddress, SERVERPORT);
// outgoing stream redirect to socket
OutputStream out = s.getOutputStream();
PrintWriter output = new PrintWriter(out);
output.println("DLS");
BufferedReader input = new BufferedReader(new InputStreamReader(
s.getInputStream()));
// read line(s)
String st = input.readLine();
// . . .
isSuccessful = true;
} catch (Exception e) {
e.printStackTrace();
} finally {
s.close();
}
return isSuccessful;
}
答案 1 :(得分:0)
你只需要一个循环(IMO,比递归更容易理解):
for (int i = 0; i < MAX_ATTEMPTS; i++) {
try {
run();
break; // no exception: break out of the loop.
}
catch (UnknownHostException | IOException e) {
Thread.sleep(DELAY_BETWEEN_ATTEMPTS_IN_MILLIS);
}
}
当然,您不能再从run()
方法本身捕获异常。
答案 2 :(得分:0)
你正在编写一个函数,在没有延迟的情况下在失败时回避。这是不可取的,原因有两个,其中一个原因是你可以吹掉调用堆栈(如你所见)。
一般来说,我建议将可能失败的代码拉出到自己的函数中,然后将其专门返回成功与可重试失败相对于其他失败(例如使用自定义“RetryableFailure”子类的异常)。然后你可以从代码中调用它,如果有必要,可以在延迟之后重试。
E.g。
class RetryableException extends Exception {
public RetryableException(Throwable: underlying) {
...
}
}
public void tryIt() throws RetryableException {
Socket s = null;
try {
s = new Socket(myIpAddress, SERVERPORT);
// outgoing stream redirect to socket
OutputStream out = s.getOutputStream();
PrintWriter output = new PrintWriter(out);
output.println("DLS");
BufferedReader input = new BufferedReader(new InputStreamReader(
s.getInputStream()));
// read line(s)
String st = input.readLine();
// . . .
} catch (UnknownHostException e) {
throw new RetryableException(e);
} catch (IOException e) {
throw new RetryableException(e);
} finally {
if (s != null) {
s.close();
}
}
}
public void run() {
boolean succeeded = false;
while (! succeeded) {
try {
tryIt();
succeeded = true;
} catch (RetryableException e) {
// log
Thread.sleep(1000);
}
}
}
另请注意以下事项:
finally
块onCreate
调用此内容(正如您在评论中所述),您可能希望将其重组为Service
而不是阻止主线程。 - http://developer.android.com/reference/android/app/Service.html