Fix not working scheduled reconnect

Documentation for postDelayed:
> Causes the Runnable r to be added to the message queue, to be run
> after the specified amount of time elapses.
> The runnable will be run on the thread to which this handler
> is attached.
> <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
> Time spent in deep sleep will add an additional delay to execution.

TL;DR: if the CPU is in deep sleep, the postDelayed runnable won't be executed.
This commit is contained in:
Jannis Mattheis
2020-05-30 19:59:28 +02:00
parent fe9e431a2b
commit 91dfd881e1
2 changed files with 36 additions and 14 deletions

View File

@@ -1,7 +1,9 @@
package com.github.gotify.service;
import android.app.AlarmManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.os.Handler;
import com.github.gotify.SSLSettings;
import com.github.gotify.Utils;
@@ -9,6 +11,7 @@ import com.github.gotify.api.Callback;
import com.github.gotify.api.CertUtils;
import com.github.gotify.client.model.Message;
import com.github.gotify.log.Log;
import java.util.Calendar;
import java.util.concurrent.TimeUnit;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
@@ -17,8 +20,9 @@ import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
public class WebSocketConnection {
class WebSocketConnection {
private final ConnectivityManager connectivityManager;
private final AlarmManager alarmManager;
private OkHttpClient client;
private final Handler reconnectHandler = new Handler();
@@ -41,8 +45,10 @@ public class WebSocketConnection {
String baseUrl,
SSLSettings settings,
String token,
ConnectivityManager connectivityManager) {
ConnectivityManager connectivityManager,
AlarmManager alarmManager) {
this.connectivityManager = connectivityManager;
this.alarmManager = alarmManager;
OkHttpClient.Builder builder =
new OkHttpClient.Builder()
.readTimeout(0, TimeUnit.MILLISECONDS)
@@ -119,14 +125,25 @@ public class WebSocketConnection {
}
}
public synchronized void scheduleReconnect(long millis) {
reconnectHandler.removeCallbacks(reconnectCallback);
Log.i(
"WebSocket: scheduling a restart in "
+ TimeUnit.SECONDS.convert(millis, TimeUnit.MILLISECONDS)
+ " second(s)");
reconnectHandler.postDelayed(reconnectCallback, millis);
public synchronized void scheduleReconnect(long seconds) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Log.i(
"WebSocket: scheduling a restart in "
+ seconds
+ " second(s) (via alarm manager)");
final Calendar future = Calendar.getInstance();
future.add(Calendar.SECOND, (int) seconds);
alarmManager.setExact(
AlarmManager.RTC_WAKEUP,
future.getTimeInMillis(),
"reconnect-tag",
this::start,
null);
} else {
Log.i("WebSocket: scheduling a restart in " + seconds + " second(s)");
reconnectHandler.removeCallbacks(reconnectCallback);
reconnectHandler.postDelayed(reconnectCallback, TimeUnit.SECONDS.toMillis(seconds));
}
}
private class Listener extends WebSocketListener {
@@ -191,7 +208,7 @@ public class WebSocketConnection {
int minutes = Math.min(errorCount * 2 - 1, 20);
onNetworkFailure.execute(minutes);
scheduleReconnect(TimeUnit.MINUTES.toMillis(minutes));
scheduleReconnect(TimeUnit.MINUTES.toSeconds(minutes));
}
super.onFailure(webSocket, t, response);

View File

@@ -1,5 +1,6 @@
package com.github.gotify.service;
import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
@@ -30,7 +31,6 @@ import com.github.gotify.messages.Extras;
import com.github.gotify.messages.MessagesActivity;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class WebSocketService extends Service {
@@ -92,10 +92,15 @@ public class WebSocketService extends Service {
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
connection =
new WebSocketConnection(
settings.url(), settings.sslSettings(), settings.token(), cm)
settings.url(),
settings.sslSettings(),
settings.token(),
cm,
alarmManager)
.onOpen(this::onOpen)
.onClose(() -> foreground(getString(R.string.websocket_closed)))
.onBadRequest(this::onBadRequest)
@@ -121,7 +126,7 @@ public class WebSocketService extends Service {
return;
}
connection.scheduleReconnect(TimeUnit.SECONDS.toMillis(5));
connection.scheduleReconnect(5);
}
private void onBadRequest(String message) {