Dex*_*ter 5 java android abstract-class
如果抛出一些异常,我已经让这个抽象类自动重试网络调用。
InterruptedException&
之后重试UnknownHostException。public abstract class AutoRetry {
private Object dataToReturn = null;
public Object getDataToReturn() {
return this.dataToReturn;
}
public AutoRetry() {
short retry = -1;
while (retry++ < StaticData.NETWORK_RETRY) {
try {
Thread.sleep(retry * StaticData.NETWORK_CALL_WAIT);
this.dataToReturn = doWork();
break;
} catch (InterruptedException | UnknownHostException e) {
e.printStackTrace();
this.dataToReturn = null;
return;
} catch (IOException e) {
e.printStackTrace();
}
}
}
protected abstract Object doWork() throws IOException;
}
Run Code Online (Sandbox Code Playgroud)
我使用它如下:
final Object dataAfterWork = new AutoRetry() {
@Override
protected Object doWork() throws IOException {
return; //a network call which returns something
}
}.getDataToReturn();
Run Code Online (Sandbox Code Playgroud)
那么这个实现好/正确吗?
这看起来不错,但我会将正在运行的任务与重试分开。也要使用泛型,不要乱扔Object。
使用Java 8lambda 和return方法的 :
public static <T> Optional<T> doWithRetry(final Supplier<T> t) {
for (int retry = 0; retry <= StaticData.NETWORK_RETRY; ++retry) {
try {
Thread.sleep(retry * StaticData.NETWORK_CALL_WAIT);
return Optional.of(t.get());
} catch (InterruptedException | UnknownHostException e) {
LOGGER.log(Level.SEVERE, "Call failed.", e);
return Optional.empty();
} catch (IOException e) {
LOGGER.log(Level.WARNING, "Call failed. Retry.", e);
}
}
LOGGER.log(Level.SEVERE, "Call failed. Retries exceeded.");
return Optional.empty();
}
Run Code Online (Sandbox Code Playgroud)
另外,使用真正的记录器,而不是printStackTrace......
用法:
final String data = doWithRetry(() -> {
//do stuff
});
Run Code Online (Sandbox Code Playgroud)
如果您的 lambda 需要抛出异常,您需要定义自己的@FunctionalInterface:
@FunctionalInterface
interface StuffDoer<T> {
T doStuff() throws Exception;
}
Run Code Online (Sandbox Code Playgroud)
并在方法签名中使用它,您需要处理 generic Exception。
Java 8 之前的用法:
final String data = doWithRetry(new StuffDoer<T>() {
@Override
public T get() throws Exception {
return null;
}
});
Run Code Online (Sandbox Code Playgroud)