Невозможно создать обработчик внутри потока, который не вызвал Looper.prepare() в CountDownTimer

У меня есть услуга. И есть метод, называемый onServiceUpdate(). Этот метод аналогичен onLocationChanged() в API Карт Google.

Поэтому я хочу запустить CountDownTimer внутри метода onServiceUpdate(), но показывая такую ошибку:

Can't create handler inside thread that has not called Looper.prepare()
    java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
            at android.os.Handler.<init>(Handler.java:200)
            at android.os.Handler.<init>(Handler.java:114)
            at android.os.CountDownTimer$1.<init>(CountDownTimer.java:114)
            at android.os.CountDownTimer.<init>(CountDownTimer.java:114)
            at skripsi.ubm.studenttracking.Service2$6.<init>(Service2.java:317)
            at skripsi.ubm.studenttracking.Service2.onServiceUpdate(Service2.java:317)

Это мой код:

    @Override
    public void onServiceUpdate(ServiceState state)
    {
final float[] distance = new float[2];
        Location.distanceBetween(state.getGeoPoint().getLatitude(), state.getGeoPoint().getLongitude(), 6.130607787619352,106.81839518499267, distance);
        if (distance[0] > 25.0)
        {

                        CountDownTimer cdt5  = new CountDownTimer(total_onServiceUpdate,1000) {
                            @Override
                            public void onTick(long millisUntilFinished) {
                                total_onServiceUpdate = millisUntilFinished/1000;
                            }

                            @Override
                            public void onFinish() {
                                sendSMS();
                                stopSelf();
                            }
                        }.start();

        }

Ответ 1

onServiceUpdate() - это асинхронная задача, которая запускает и уведомляет вас, следовательно, представляет собой фоновый поток. все, что вам нужно сделать, это вызвать timer.start(); из основного потока, Служба фактически работает на главной теме, это намерение, которое не так, ваше решение идет по пути

new Handler(Looper.getMainLooper()).post(new Runnable() {           
        @Override
        public void run() {
            CountDownTimer cdt5  = new CountDownTimer(total_onServiceUpdate,1000) {
                        @Override
                        public void onTick(long millisUntilFinished) {
                            total_onServiceUpdate = millisUntilFinished/1000;
                        }

                        @Override
                        public void onFinish() {
                            sendSMS();
                            stopSelf();
                        }
                    }.start();
        }
    });

теперь вы можете продолжить сэр. Всегда коллирует коды флиртовать с экраном на главном Looper

Надеюсь, поможет

Ответ 2

Я думаю, проблема в том, что в вашей sendSMS() вы пытаетесь сделать что-то, что требует UIThread (например, обновление представления). Попробуй это:

Handler mHandler = new Handler() {
 public void handleMessage(Message msg){
    sendSMS();
}};

Измените метод onFinish на

@Override
public void onFinish() {
    mHandler.sendEmptyMessage(0);
    stopSelf();
}

Ответ 3

Вы не можете обновлять действие gui из службы через обработчик, потому что обработчик должен быть создан в потоке gui.

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

Ответ 4

Android:

Попробуйте это до вызова обработчика

if (Looper.MyLooper() == null) {Looper.Prepare(); } }