Android останавливает фоновую службу после сбоя активности

В начале я хотел бы извиниться за плохой английский.

Есть моя проблема:

У меня есть служба в Android, которая работает в фоновом режиме, когда выполняется активность. (Этот сервис синхронизирует пользовательские данные с сервером через заданные промежутки времени).

public class CService extends Service
{
   private Boolean isDestroyed;



@Override
    public int onStartCommand (Intent intent, int flags, int startId)
    {
            if (intent != null)
            {
                   new Thread(new Runnable()
                   {
                   //run new thread to disable flush memory for android and destroy this service
                           @Override
                           public void run ()
                           {
                                     this.isDestroyed = Boolean.FALSE
                                     while(!this.isDestroyed)
                                     {
                                     //loop until service isn't destroyed
                                     }
                            }

                    }).start();
            }
            return Service.START_NOT_STICKY;

    }

    @Override
    public void onDestroy ()
    {
           //THIS ISNT CALLED FROM uncaughtException IN ACTIVITY BUT from onDestroy method is this called.

           //when is service destroyed then onDestroy is called and loop finish
           this.isDestroyed = Boolean.TRUE;
    }

}

И запускается из активности в onCreateMethod. Это действие реализует Thread.UncaughtExceptionHandler и регистрируется в методе onCreate для перехвата всех непредвиденных исключений в действии. Когда что-то в действии вызывает метод исключения uncaughtException, и служба должна останавливаться с помощью stopService(serviceIntent); Но onDestoy в сервис не зовется. Но когда вызывается метод onDestroy в действии (пользователь нажимает кнопку «Назад»), служба успешно останавливается, и вызывается onDestroy в CService.

    public class CActivity extends Activity implements Thread.UncaughtExceptionHandler
    {
            private Thread.UncaughtExceptionHandler defaultUEH;

        @Override
        protected void onCreate (Bundle savedInstanceState)
        {

            this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();

            // create intent for service
            Intent serviceIntent = new Intent(this, CService.class);
            // run service
            startService(serviceIntent);

            //set default handler when application crash
            Thread.setDefaultUncaughtExceptionHandler(this);
            super.onCreate(savedInstanceState);
        }

        @Override
        public void uncaughtException (Thread thread, Throwable ex)
        {
            //THIS DOESN'T WORK

            //when global exception in activity is throws then this method is called. 
            Intent serviceIntent = new Intent(this, CService.class);
            //method to service stop is called. BUT THIS METHOD DON'T CALL onDestroy in CService
            stopService(serviceIntent);
            defaultUEH.uncaughtException(thread, ex);       
        }

        @Override
        public void onDestroy ()
        {
            //this work fine
            Intent serviceIntent = new Intent(this, CService.class);
            stopService(serviceIntent);
            super.onDestroy();
            }


    }

Мне нужно остановить фоновую службу при сбое активности. Потому что, когда Android закрывает активность и запускает предыдущую активность в стеке (это экран входа в систему), пользователь теперь не регистрируется.

Спасибо за предложения.


person Kamikazee    schedule 08.11.2012    source источник
comment
ваша служба запускается из другого процесса?   -  person Korniltsev Anatoly    schedule 08.11.2012
comment
служба запускается и останавливается из одного и того же действия, выполняемого в методе onCreate, и останавливается в методе uncaughtException.   -  person Kamikazee    schedule 08.11.2012


Ответы (2)


Попробуй это

    Thread.currentThread().setUncaughtExceptionHandler(this);

UPD
это обработчик исключений Android по умолчанию

private static class UncaughtHandler implements Thread.UncaughtExceptionHandler {
        public void uncaughtException(Thread t, Throwable e) {
            try {
                // Don't re-enter -- avoid infinite loops if crash-reporting crashes.
                if (mCrashing) return;
                mCrashing = true;

                if (mApplicationObject == null) {
                    Slog.e(TAG, "*** FATAL EXCEPTION IN SYSTEM PROCESS: " + t.getName(), e);
                } else {
                    Slog.e(TAG, "FATAL EXCEPTION: " + t.getName(), e);
                }

                // Bring up crash dialog, wait for it to be dismissed
                ActivityManagerNative.getDefault().handleApplicationCrash(
                        mApplicationObject, new ApplicationErrorReport.CrashInfo(e));
            } catch (Throwable t2) {
                try {
                    Slog.e(TAG, "Error reporting crash", t2);
                } catch (Throwable t3) {
                    // Even Slog.e() fails!  Oh well.
                }
            } finally {
                // Try everything to make sure this process goes away.
                Process.killProcess(Process.myPid());
                System.exit(10);
            }
        }
    }

Я считаю, что вы не получаете вызов onDestroy(), потому что обработчик исключений Android по умолчанию просто уничтожает весь процесс System.exit(). Вы можете попробовать не вызывать defaultUEH.uncaughtException(thread, ex); или позвоните позже после того, как (если) ваша служба будет уничтожена.

person Korniltsev Anatoly    schedule 08.11.2012
comment
Это не работает. Потому что setUncaughtExceptionHandler(this); является статическим методом, а currentThread() не является статическим методом. Но спасибо за ответ - person Kamikazee; 08.11.2012
comment
setDefaultUncaughtExceptionHandler является статическим - person Korniltsev Anatoly; 08.11.2012
comment
ваше право, я использую статический метод. Но если я не использую статический метод setUncaughtExceptionHandler, stopService() также не вызывает onDestroy. - person Kamikazee; 08.11.2012

Чувак, кстати, почему ты выполняешь действия в методе onCreate? Поскольку в документации говорится, что этот метод вызывается из основного потока, мне действительно интересно, как он вообще работает. Вы должны выполнять любые тяжелые вычисления из другого потока.

http://developer.android.com/reference/android/app/Service.html

Когда сервисный компонент действительно создается по любой из этих причин, все, что на самом деле делает система, — это создает экземпляр компонента и вызывает его onCreate() и любые другие подходящие обратные вызовы в основном потоке. Служба должна реализовать их с соответствующим поведением, например, создать вторичный поток, в котором она выполняет свою работу.

person Korniltsev Anatoly    schedule 08.11.2012
comment
Извините, я делаю ошибку, когда публикую здесь вопрос, потому что я запускаю службу из onStartCommand вместо onCreate. Исправляю первый пост и исправляю вопрос. Я не копирую и не вставляю в вопрос, и когда я пишу код, я делаю ошибку. И я использую другой поток, чтобы предотвратить уничтожение службы Android. - person Kamikazee; 08.11.2012