2012-06-21 7 views
7

Когда этот обратный вызов сделан в моем приложении, мне нужно немного поработать (чтение & записи в SQL db через ORM lib и ряд вычислений на основе расстояния). Естественно, меня беспокоит не блокирование основного потока пользовательского интерфейса, поэтому я пытался (безуспешно) выяснить, является ли это потоком, на котором выполняется обратный вызов. Если это так, я намереваюсь выполнить всю вышеупомянутую работу над AsyncTask, вызванную при обратном вызове. Эта же AsyncTask будет получать события из двух отдельных классов активности. (Ответ на ввод пользователя и т. Д.)onLocationChanged callback делается на какой поток? Основной поток пользовательского интерфейса?

Большая часть обсуждения, которое я нашел вокруг этого обратного вызова, похоже, основывается на людях, пытающихся изменить поток, на который фактически получен обратный вызов. Для меня это не имеет смысла. Разумеется, платформа определяет контекст этого обратного вызова, и разумная вещь, которую нужно делать, когда она получена, выгружает любую серьезную работу в другой поток, для которой AsyncTask кажется подходящим.

Если кто-то может нарисовать успешный образец, который они использовали здесь, это было бы очень полезно.

ответ

7

Согласно справочной документации Android для LocationManager:

Вызывающего поток должен быть нитью петлителя, такие как основная нить вызывающей активность.

Это означает, что нить, которая инициализирует обратный вызов, должна быть главной нитью или резьбой Looper.

Я нашел лучший способ справиться с этим - зарегистрировать приемник OnLocationChanged на главной теме. Затем в моем обратном вызове я создам Runnable для отправки в фоновый поток, где я буду выполнять любые длительные задачи (например, запись в базу данных).

ExecutorService mThreadPool = Executors.newSingleThreadExecutor(); 

@Override 
public void onLocationChanged(Location location) { 
    mThreadPool.execute(new Runnable() { 
     @Override 
     public void run() { 
      // Perform your long-running tasks here. 
      //... 
     } 
    }); 
} 
+0

Из документации действительно кажется, что нить, на которой onLocationChanged называется обратно, зависит от параметров, передаваемых в зависимости от того, используется requestLocationUpdate (..) вызов. Кроме того, если Looper не является одним из параметров, тогда обратный вызов будет выполняться в контексте основного потока пользовательского интерфейса. Вам нужно прочитать немного больше о Loopers. Решение выше выглядит разумным. Теперь мне интересно, как это сравнивается с использованием AsyncTask с точки зрения производительности. Поэтому я пойду и прочитаю документацию, как я должен был сделать в первую очередь. Спасибо за помощь. –

+0

Вы правы, существует несколько вариантов регистрации обратного вызова «LocationListener». Чтение документации, безусловно, рекомендуется. Вышеупомянутое решение примерно эквивалентно использованию «AsyncTask». Я считаю, что если вы посмотрите на источник для класса «AsyncTask», вы увидите, что он использует внутреннюю службу «ExecutorService». Однако, если вам не нужно взаимодействовать с потоком пользовательского интерфейса, когда ваша задача будет завершена, вы обнаружите, что 'AsyncTask' делает больше, чем вам нужно. – twaddington

Смежные вопросы