Thread.sleep () не позволяет другим потокам работать?

1

Я делаю приложение для Android и создал класс для более простого разделения и управления кодом, связанным с определением местоположения пользователя. Так как FusedLocationProviderClient требуется некоторое время, чтобы дать ответ и выполнить код внутри слушателей onSuccess или onFailure, я создал метод (waitForLocation()), который в основном ожидает выполнения одного из слушателей или превышения лимита времени.

Метод waitForLocation() - это метод блокировки, который ожидает, пока значение gotResponse станет true чтобы позволить остальной части потока продолжить (значение gotResponse также станет true если превышен лимит времени).

Проблема заключается в том, что для остановки выполнения кода до gotResponse пор, пока значение gotResponse станет true, я использую метод Thread.sleep(), но все фоновые задачи, такие как CountDownTimer и слушатели, похоже, также CountDownTimer вместе с основным поток (CountDownTimer не тикает и слушатели никогда не выполняются).

Пожалуйста помоги! Заранее спасибо

Это мой класс:

package com.sserrano.stormy;

import android.app.Activity;
import android.location.Location;
import android.os.CountDownTimer;
import android.support.annotation.NonNull;
import android.util.Log;

import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;


public class UserLocationManager {

    public static final String TAG = UserLocationManager.class.getSimpleName();

    private FusedLocationProviderClient locationClient;
    private Activity instActivity;
    private double[] coords = {37.8267, -122.4233}, defaultCoords = {37.8267, -122.4233};
    private volatile boolean gotResponse = false;

    UserLocationManager(Activity instActivity){
        this.instActivity = instActivity;
        locationClient = LocationServices.getFusedLocationProviderClient(instActivity);
    }

    public double[] getLastCoords() {
        try {
            locationClient.getLastLocation().
                    addOnSuccessListener(instActivity, new OnSuccessListener<Location>() {
                        @Override
                        public void onSuccess(Location location) {
                            if(location != null) {
                                coords = new double[]
                                        {location.getLatitude(), location.getLongitude()};
                            }
                            gotResponse = true;
                        }
                    }).addOnFailureListener(instActivity, new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            gotResponse = true;
                        }
                    });
        } catch (SecurityException e){
            return defaultCoords;
        }

        waitForLocation();
        return coords;
    }


    public double[] getDefaultCoords(){
        return defaultCoords;
    }

    private void waitForLocation(){
        new CountDownTimer(5000, 5000){
            @Override
            public void onFinish() {
                gotResponse = true;
                Log.w(TAG, "Timed out waiting the result of the location request.");
            }

            @Override
            public void onTick(long millisUntilFinished) {

            }
        };
        try{
            while(!gotResponse) {
                Thread.sleep(Constants.getSleepIntervalDuration());
            }
        } catch (InterruptedException e) {
            Log.w(TAG, "Interrupted while waiting the result of the location request." +
                    " The app will likely act like if the location was not received, " +
                    "even if it was.");
        }
        gotResponse = false;
    }
}
Теги:
multithreading

1 ответ

0
  1. Это будет спать поток пользовательского интерфейса. Это абсолютный запрет. Боюсь, вы неправильно использовали CountDownTimer и асинхронную операцию. Пожалуйста, посмотрите на другие примеры.
  2. Также вы забыли вызвать .start() для CountDownTimer onFinish, это никогда не произойдет.
  3. Присвойте таймер переменной-члену, затем он будет действовать до тех пор, пока не будет вызван onFinish, и вы можете установить свой gotResponse.
  • 0
    Я думаю, вы имели в виду "асинхронную" операцию. Кроме того, неверно предполагать, что CountDownTimer получит GC'd, если вы не держите ссылку на него; он регистрирует внутренний Handler который поддерживает ссылку, пока таймер не завершится.
  • 0
    @ greeble31 да, моя телефонная клавиатура обманула меня там. Это не собирать мусор? Полезно знать, я попробую.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню