#java #android #multithreading #performance #location
#java #Android #многопоточность #Производительность #Расположение
Вопрос:
autoSearch_button.setOnClickListener(view -> {
grant_permission();
check_location_enableornot();
lastButton_pressed = view.getId();
ExampleRunnable exampleRunnable = new ExampleRunnable(20);
Thread thread = new Thread(exampleRunnable);
thread.start();
thread.join();
});
public class ExampleRunnable implements Runnable {
private int kmRadius;
private double lat =0 , longi =0 ;
public ExampleRunnable(int i) {
this.kmRadius = i;
}
@Override
public void run() {
lastLocation();
}
private void lastLocation(){
Log.i(TAG, "lastLocation: " Thread.currentThread().getName());
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(MainActivity.this);
// for now being assume that i have declared
@SuppressLint("MissingPermission") Task<Location> locationTask = fusedLocationProviderClient.getLastLocation();
locationTask.addOnSuccessListener(location -> {
if (location != null) {
//We have a location
Log.d(TAG, "run: last location" Thread.currentThread().getName()););
this.lat = location.getLatitude();
this.longi = location.getLongitude();
print();
} else {
Log.d(TAG, "onSuccess: Location was null... calling robust");
}
}).addOnFailureListener(e -> Log.e(TAG, "onFailure: " e.getLocalizedMessage() ));
}
}
public synchronized void print(){
Log.d(TAG, "print: " Thread.currentThread.getName());
}
}
Выводите то, что я хочу, в logcat
- lastlocation: thread4
- выполнить: поток lastlocation4
- печать: thread4
Но какой результат я получаю — lastlocation: thread4 // run: lastLocation main // print: main
Я хочу обрабатывать местоположение и работать над ним в определенном потоке
Ответ №1:
locationTask.addOnSuccessListener
При этом не запускается прослушиватель, он просто регистрирует блок кода, который следует за locationTask
объектом, и этот объект может делать с ним все, что захочет.
Очевидно (и это часто встречается в системах обработки событий, подобных этой), какой-то поток завершает выполнение некоторого события, и, как следствие этого, слушатели для этого события запускаются прямо тогда и там, в этом потоке.
У вас есть два решения:
- Потому что любое событие в конечном итоге запускает прослушиватель (ваш код не помогает объяснить, где это; то, что заставляет объект
locationTask
, на который указывает переменная, переходить в состояние «успех», тем самым вызывая вашего прослушивателя), происходит в том потоке, в котором вы хотите, чтобы это произошло, а не в main . - Не запускайте поток для регистрации успешного прослушивателя; запустите поток внутри вашего успешного прослушивателя (поэтому вместо
Log.d(TAG, "run: last location"...
этого запустите поток).
Иногда системы обработки событий настраиваются, и вы можете указать ему запускать такие события в других потоках, но это случается редко. Если библиотека не поддерживает это (а я сомневаюсь, что это так), вам придется написать методы-оболочки или обернуть всю библиотеку, чтобы получить это.