SensorEventListener в отдельной теме

Это похоже на основной вопрос, но после того, как вы искали какое-то время и играли с ним, я пришел к выводу, что какая-то помощь будет оценена. Я хотел бы запустить SensorEventListener в отдельном потоке из пользовательского интерфейса, так что вычисления, которые должны произойти при входе в события, не замедляют работу пользовательского интерфейса.

Моя последняя попытка выглядит так:

class SensorThread extends Thread { SensorManager mSensorManager; Sensor mSensor; public void run() { Log.d( "RunTag", Thread.currentThread().getName() ); // To display thread mSensorManager = (SensorManager)getSystemService( SENSOR_SERVICE ); mSensor = mSensorManager.getDefaultSensor( Sensor.TYPE_ACCELEROMETER ); MySensorListener msl = new MySensorListener(); mSensorManager.registerListener(msl, mSensor, SensorManager.SENSOR_DELAY_UI ); } private class MySensorListener implements SensorEventListener { public void onAccuracyChanged (Sensor sensor, int accuracy) {} public void onSensorChanged(SensorEvent sensorEvent) { Log.d( "ListenerTag", Thread.currentThread().getName() ); // To display thread } } 

В действии (или службе) onCreate () я создаю объект SensorThread и вызываю его метод start (). Как и следовало ожидать, в журнале отладки отображается запись «RunTag» в новом потоке. Но onSensorChanged () «ListenerTag» работает в основном потоке, хотя его объект создается в новом потоке. Как это изменить?

Вы можете получить событие датчика в фоновом потоке. Вместо

 mSensorManager.registerListener(msl, mSensor, SensorManager.SENSOR_DELAY_UI ); 

Вы можете объявить его обработчиком со ссылкой на вторичный поток. Пробег цикла потока выглядит следующим образом:

 ... run { Looper.prepare; Handler handler = new Handler(); ... mSensorManager.registerListener(msl, mSensor, SensorManager.SENSOR_DELAY_UI, handler ); Looper.loop(); } ... 

Похоже, что SensorManager фактически отвечает за вызов метода onSensorChanged, и я не думаю, что тот факт, что registerListener вызывается в этом отдельном потоке, будет иметь какое-то значение. Проще всего сделать это, возможно, сделать onSensorChanged return мгновенно, делегируя весь тяжелый подъем в отдельный поток. Или, возможно, к ASyncTask, который, кажется, является официальным «правильным способом» для совершения подобных действий.

Немного поздно, но если другие все еще хотят знать, вот хороший способ добиться этого. Как всегда, при многопоточности, убедитесь, что вы знаете, что делаете, и найдите время, чтобы это было правильно, чтобы избежать этих странных ошибок. Повеселись!

Члены класса:

 private HandlerThread mSensorThread; private Handler mSensorHandler; 

В OnCreate или при регистрации:

 mSensorThread = new HandlerThread("Sensor thread", Thread.MAX_PRIORITY); mSensorThread.start(); mSensorHandler = new Handler(mSensorThread.getLooper()) //Blocks until looper is prepared, which is fairly quick yourSensorManager.registerListener(yourListener, yourSensor, interval, mSensorHandler); 

Когда вы регистрируетесь без регистрации, также выполните:

 mSensorThread.quitSafely(); 

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

 public void run() { Log.d( "RunTag", Thread.currentThread().getName() ); // To display thread mSensorManager = (SensorManager)getSystemService( SENSOR_SERVICE ); mSensor = mSensorManager.getDefaultSensor( Sensor.TYPE_ACCELEROMETER ); MySensorListener msl = new MySensorListener(); Looper.perpare; Handler hndlr = new Handler(); mSensorManager.registerListener(msl, mSensor, SensorManager.SENSOR_DELAY_UI, hndlr); Looper.loop; } 

Получите обработчик потока и зарегистрируйте слушателя в этом потоке. Например:

 public void run() { Sensor sensor = this.sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY); Looper.prepare(); Handler gHandler = new Handler(); this.sensorManager.registerListener(gravitySensorEventListener, sensor, SensorManager.SENSOR_DELAY_NORMAL, gHandler); Looper.loop(); } 

Надеется, что это поможет вам.

Intereting Posts
Альтернатива для String.join в Android? Как использовать два курсора и CursorJoiner в LoaderManager в android Как создавать приложения для Android для всех разрешений? Как я могу получить размер файла во время загрузки с URL-адреса (используя http-соединение)? Как не показывать приложение в списке последних приложений в ICS? ExcludeFromRecents не работает Android – Ошибка при подписании моего apk wit jarsigner Для вызова требуется разрешение, которое может быть отклонено пользователем Как получить значок, связанный с определенной учетной записью, из AccountManager.getAccounts () Android удаляет панель действий приложения Как использовать конвертер Gson в RetroFit? Отложенные события на Android Как различать длительное нажатие клавиши и регулярное нажатие клавиши? Robolectric говорит, что «AndroidManifest.xml не найден» Android TransitionDrawable с несколькими элементами Как ограничить минимальный размер урожая изображения в андроиде