Служба переднего плана не работает постоянно

В моем приложении я использую службу переднего плана, которая должна работать постоянно. Иногда служба переднего плана останавливается. При каких обстоятельствах ОС может убить мой сервис (даже если памяти достаточно, батарея полностью заряжена, телефон заряжается)?

Вот как выглядит мой код до сих пор:

public class ServiceTest extends Service {

    public static Thread serverThread = null;
    public Context context = this;

    public ServiceTest(Context context) {
        super();
        this.context = context;
    }

    public ServiceTest() {

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);

        if (this.serverThread == null) {
            this.serverThread = new Thread(new ThreadTest());
            this.serverThread.start();
        }

        return START_STICKY;
    }

    private class ThreadTest implements Runnable {

        @Override
        public void run() {
            Intent notificationIntent = new Intent(context, MainActivity.class);
        notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
                notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);

        Notification notification = new NotificationCompat.Builder(context)
                .setContentTitle("Notification title")
                .setContentText("Notification text")
                .setContentIntent(pendingIntent)
                .setAutoCancel(false)
                .setSmallIcon(R.drawable.android)
                .setOngoing(true).build();

                startForeground(101, notification);

                while(true){
                    //work to do
                }
        }


    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

}

person Madalina    schedule 13.08.2018    source источник
comment
В какой ОС Android вы работаете? Это Орео?   -  person Vinayak B    schedule 13.08.2018
comment
Не на Oreo до сих пор. Только что с андроида 4-7   -  person Madalina    schedule 13.08.2018
comment
как запустить эту службу?   -  person Vinayak B    schedule 13.08.2018
comment
в MainActivity я проверяю, запущена ли Служба, если нет, я запускаю ее, используя: Intentintent = new Intent(getApplicationContext(), ServiceTest.getClass()); намерение.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); if (!isMyServiceRunning(getApplicationContext(), ServiceTest.getClass())) { startService(intent); }   -  person Madalina    schedule 13.08.2018
comment
Я также проверяю, есть ли событие BOOT_COMPLETED, используя BroadcastReceiver, и запускаю службу оттуда, используя тот же метод.   -  person Madalina    schedule 13.08.2018
comment
Опасный код реализации и стиль реализации.... хотя и дал ответ....   -  person sandhya sasane    schedule 13.08.2018
comment
Благодарю за ваш ответ. Я все еще новичок в программировании для Android, я ценю, что вы указали, где были проблемы. Я еще раз взгляну на официальную документацию Android, и на этот раз я прочитаю ее более внимательно.   -  person Madalina    schedule 13.08.2018


Ответы (1)


В вашем коде нет ни одной... Many problems... Возможно, вы получаете "0 ошибок", так как это синтаксически правильно, но это androidicaly неправильно, ваши basics плохие, чтение android documentation и implementation очень плохое. Android никогда не работает очень плохо...

Проблема : 1

Знаете ли вы, что для службы обычно вы должны использовать override onCreate, onStartCommand, onBind, onDestroy методы....?

Я не вижу там onDestroy....!!

Проблема : 2

Вы знаете, как уведомить...? Ваша реализация onStartCommand снова не имеет смысла.

СОХРАНЯЙТЕ ПУСТОЙ ПРОСТО ВЕРНУТЬСЯ START_STICKY

Проблема : 3

Как вы собираетесь запускать это с ограничениями на выполнение в фоновом режиме...? Сначала уведомите Android, сделав уведомление только в oncreate и при необходимости с помощью startforeground...

Я не вижу его там.... ты пытаешься сделать это в onstartcommand и опять очень плохо...

Ну... взгляните на рабочий код ниже:

public class RunnerService extends Service
{
NotificationManager mNotifyManager;
NotificationCompat.Builder mBuilder;
NotificationChannel notificationChannel;
String NOTIFICATION_CHANNEL_ID = "1";

public RunnerService() { }

@Override
public void onCreate()
{
    super.onCreate();

    Log.d("RUNNER : ", "OnCreate... \n");

    Bitmap IconLg = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_foreground);

    mNotifyManager = (NotificationManager) getApplicationContext().getSystemService(NOTIFICATION_SERVICE);
    mBuilder = new NotificationCompat.Builder(this, null);
    mBuilder.setContentTitle("My App")
            .setContentText("Always running...")
            .setTicker("Always running...")
            .setSmallIcon(R.drawable.ic_menu_slideshow)
            .setLargeIcon(IconLg)
            .setPriority(Notification.PRIORITY_HIGH)
            .setVibrate(new long[] {1000})
            .setVisibility(Notification.VISIBILITY_PUBLIC)
            .setOngoing(true)
            .setAutoCancel(false);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
    {
        notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "My Notifications", NotificationManager.IMPORTANCE_HIGH);

        // Configure the notification channel.
        notificationChannel.setDescription("Channel description");
        notificationChannel.enableLights(true);
        notificationChannel.setLightColor(Color.RED);
        notificationChannel.setVibrationPattern(new long[]{1000});
        notificationChannel.enableVibration(true);
        notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
        mNotifyManager.createNotificationChannel(notificationChannel);

        mBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
        startForeground(1, mBuilder.build());
    }
    else
    {
        mBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
        mNotifyManager.notify(1, mBuilder.build());
    }
}

@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
    Log.d("RUNNER : ", "\nPERFORMING....");

    return START_STICKY;
}

@Override
public void onDestroy()
{
    Log.d("RUNNER : ", "\nDestroyed....");
    Log.d("RUNNER : ", "\nWill be created again automaticcaly....");
    super.onDestroy();
}


@Override
public IBinder onBind(Intent intent)
{
    // TODO: Return the communication channel to the service.
    throw new UnsupportedOperationException("NOT_YET_IMPLEMENTED");
}
}

Как проверить....???

Удалите приложение из списка недавних, и вы должны увидеть в своих журналах сообщение "Performing" в logcat...

В каких условиях он останавливается...?

Он никогда не останавливается (до следующей загрузки ..!!) ... Да, он останавливается, когда пользователь принудительно останавливает приложение. И редко, если система обнаруживает, что у нее очень мало ресурсов .... что, по-видимому, происходит очень редко, поскольку Android со временем значительно улучшился ....

Как начать....?????

Везде, где это может быть от mainactivity или от receiver или от любого class:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
        {
            context.startForegroundService(new Intent(context, RunnerService.class));

        }
        else
        {
            context.startService(new Intent(context, RunnerService.class));

        }

Как проверить запущен сервис или нет....?

Просто не надо... Даже если вы запускаете службу сколько угодно раз.... Если она уже запущена... то она не запустится снова.... Если не запущена, то... начнется...!!

person sandhya sasane    schedule 13.08.2018
comment
Он работает очень хорошо. Большое спасибо за Ваш ответ. - person Madalina; 13.08.2018