web-dev-qa-db-fra.com

Impossible de créer un gestionnaire dans un thread qui n'a pas appelé Looper.prepare () dans CountDownTimer

J'ai un service. Et il existe une méthode appelée onServiceUpdate (). Cette méthode est similaire à onLocationChanged () dans l'API Google Maps.

Je veux donc commencer CountDownTimer à l’intérieur de la méthode onServiceUpdate () mais en affichant l’erreur comme ceci:

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)

Ceci est mon code:

    @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();

        }
13
Leonard Febrianto

onServiceUpdate () est une tâche asynchrone qui s'exécute et vous en informe, ce qui en fait un thread d'arrière-plan. tout ce que vous avez à faire est d'appeler timer.start (); à partir du thread principal, le service s’exécute sur le thread principal, c’est intentService qui ne le fait pas, votre solution suit le même chemin

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();
        }
    });

maintenant vous pouvez continuer monsieur. Appelez toujours les codes du flirt avec l’écran sur le le boucleur principal

J'espère que ça aide

22
Elltz

Vous ne pouvez pas mettre à jour une interface utilisateur d'activité à partir d'un service via un gestionnaire car ce dernier doit être créé dans le thread d'interface graphique.

à la place, vous devez envoyer une émission à partir de votre service et implémenter un émetteur local dans l'activité qui obtient cette émission

0
k3b

Android :

Essayez ceci avant d'appeler un gestionnaire

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

0
Amit gupta

Je pense que le problème est que dans votre sendSMS (), vous essayez de faire quelque chose qui nécessite UIThread (comme mettre à jour une vue). Essaye ça:

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

Modifier la méthode onFinish pour

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