Бессмертный Service

311
24 июня 2018, 00:50

Дело в том, что мне нужно реализовать проект, типа чата.

Решили использовать библиотеку Socket.IO. Пока FCM не рассматриваем.

Чтобы в фоновом режиме получать сообщения использую Service. Вот:

public class SocketServiceProvider extends Service {
    private Socket mSocket;
    private final String EVENT_NEW_MESSAGE = "new_message";
    private final String LOG_TAG = "SocketServiceProvider";
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    @Override
    public void onCreate() {
        super.onCreate();
        Log.e(LOG_TAG, "created()");
        realm = Realm.getDefaultInstance();
        startForeground(1, new Notification());
        if (mSocket == null)
            mSocket = BaseApplication.getSocket();
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e(LOG_TAG, "onStartedCommand()");
        startSocket();
        return START_STICKY;
    }
    private void startSocket() {
        if (mSocket.connected()){
            stopSocket();
        }
        mSocket.on(Socket.EVENT_CONNECT, onConnect);
        mSocket.on(EVENT_NEW_MESSAGE, onNewMessage);
        mSocket.connect();
    }
    private void stopSocket() {
        mSocket.off();
        mSocket.disconnect();
    }
    private Emitter.Listener onConnect = new Emitter.Listener() {
        @Override
        public void call(Object... args) {
            new Handler(Looper.getMainLooper()).post(() -> {
                if (mSocket.connected()) {
                    isOnline = true;
                    Log.e(LOG_TAG, "Подключено!");
                }
            });
        }
    };
    private Emitter.Listener onNewMessage = args -> {
        final JSONObject data = (JSONObject) args[0];
        final String username;
        final String message;
        try {
            username = data.getString("from");
            message = data.getString("message");
        } catch (JSONException e) {
            Log.e("MainActivity", e.getMessage());
            return;
        }
        Log.e(LOG_TAG, username + " написал: " + message);
    };
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e(LOG_TAG, "onDestroy()");
        stopSocket();
        ContextCompat.startForegroundService(this, new Intent(this, SocketServiceProvider.class));
    }
}

Только проблема в том, что когда телефон уходит в спящий режим, сообщения не приходят.

Попытался разбудить с AlarmManager в onTaskRemoved(), onDestroy(), безуспешно.

Еще при onDestroy() попробовал вызвать BroadcastReceiver, чтобы он запустил обратно мой Service, только не понял почему, но его метод onReceive не срабатывает.

Вот мой последний вариант, код который выложил. Там я уже использую не startService, а startForegroundService. И этот вариант сработал, по крайней мере не умирает. Только в этом случае, батарейку жестко кушает.

Пишут, что с помощью JobIntentService можно реализовать, но нигде не описано подробно.

Вопрос: Как же это сделать и как вы реализовывали такого рода задачи? И как с JobIntentService можно добиться этого?

Answer 1

Начиная с версии N ForegroundService Единственный надежный метод оставаться всегда в работе. Соответственно, думаю вам надо всетаки внедрять push, т.е. в foreground вы держите socket, потом засыпаете и делаете полл не чаще чем раз в 15 минут, либо по получению пуша, а на стороне сервера отслеживаете если пользователь не поллит, то шлете пуш. Самое печальное что Google менял чень много раз бэкграунд на разных версиях и чтобы поддерживать все сценарии начиная с 4.0 ( с сервисом и фореграунд и т.д.) нужно делать много разных вариантов.

READ ALSO
Проблема с внедрением PdfView в макет

Проблема с внедрением PdfView в макет

некорректно работает модуль Ссылка на модуль

245
Какие есть методы у Object в java?

Какие есть методы у Object в java?

Базовый класс в Java, как известно, ObjectКакие его методы вы можете назвать?

299
Нужна информация по OCAJP8

Нужна информация по OCAJP8

Если кто-нибудь недавно проходил эту сертификацию, то поделитесь, пожалуйста, какими ссылками/тренажерами/репозиториями вы пользовались...

265
Error: Invalid or corrupt jarfile как исправить

Error: Invalid or corrupt jarfile как исправить

У меня есть javafx проект, я сделал jar файл так: в структуре проекта выбрал Artifacts->нажал плюс->JAR->from modules with dependenciesДалее указал где у меня находится...

399