2015-10-01 2 views
0

Я работаю над приложением, которое запускает службу, которая проверяет уровень шума в комнате, в этом упражнении работает обработчик, который запускается каждые 250 мс, но моя проблема в том, что он работает только при активном экране, согласно моим исследованиям, обработчик работает в интерфейсе пользователя нить, следовательно, шансы его только работает на UI потоке, поэтому она работает только тогда, когда я смотрел на него, не могли бы вы помочь мне с образом я мог запустить следующий код:Как запустить автономный метод в службе Android?

handler = new Handler(); 

    final Runnable r = new Runnable() { 

     int count = 0; 
     public void run() { 

      // Get the volume from 0 to 255 in 'int' 
      double volume = 10 * mSensor.getTheAmplitude()/32768; 
      volumeToSend = (int) volume; 
      volumeVisual = ""; 

      for(int i=0; i<volumeToSend; i++){ 
       volumeVisual += "|"; 
       updateUI(); 

       Log.d("HandlerLooper", "Oscillating :" + count+1); 
      } 
      handler.postDelayed(this, 250); // amount of delay between every cycle of volume level detection + sending the data out 
     } 
    }; 

    // Is this line necessary? --- YES IT IS, or else the loop never runs 
    // this tells Java to run "r" 
    handler.postDelayed(r, 250); 

в моей службе, не делая работать в потоке пользовательского интерфейса, но только в моем сервисе?

вот мой полный код услуги:

public class VolumeListerner extends Service { 

private static String volumeVisual = ""; 
private static int volumeToSend; 
private Handler handler; 
private SoundMeter mSensor; 
/** interface for clients that bind */ 
IBinder mBinder; 
/** indicates whether onRebind should be used */ 
boolean mAllowRebind; 
/** The service is starting, due to a call to startService() */ 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 

    soundLevelCheck(); 
    return super.onStartCommand(intent, flags, startId); 
} 


private void soundLevelCheck() 
{ 
    mSensor = new SoundMeter(); 
    try { 
     mSensor.start(); 
     Toast.makeText(getBaseContext(), "Sound sensor initiated.", Toast.LENGTH_SHORT).show(); 
    } catch (IllegalStateException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    handler = new Handler(); 

    final Runnable r = new Runnable() { 

     int count = 0; 
     public void run() { 

      // Get the volume from 0 to 255 in 'int' 
      double volume = 10 * mSensor.getTheAmplitude()/32768; 
      volumeToSend = (int) volume; 
      volumeVisual = ""; 

      for(int i=0; i<volumeToSend; i++){ 
       volumeVisual += "|"; 
       updateUI(); 

       Log.d("HandlerLooper", "Oscillating :" + count+1); 
      } 
      handler.postDelayed(this, 250); // amount of delay between every cycle of volume level detection + sending the data out 
     } 
    }; 

    // Is this line necessary? --- YES IT IS, or else the loop never runs 
    // this tells Java to run "r" 
    handler.postDelayed(r, 250); 
} 



private void updateUI() 
{ 


    Intent intent = new Intent("UI_UPDATER"); 
    intent.putExtra("VolumeBars", "Volume Bars: " + String.valueOf(volumeVisual)); 
    intent.putExtra("volumeLevel","Volume Levels: " + String.valueOf(volumeToSend)); 
    LocalBroadcastManager.getInstance(this).sendBroadcast(intent); 

} 

Вся помощь будет Оценил Спасибо заранее.

+0

Я думаю, вы уже разместили этот вопрос. –

ответ

2

Android Service всегда будет работать в потоке пользовательского интерфейса, за исключением IntentService, который создаст для вас рабочий поток.

Поэтому, когда вы создаете Handler внутри службы, он будет прикрепляться к потоку пользовательского интерфейса.

Что я предлагаю вам использовать HandlerThread, который содержит петлитель, который можно передать на Handler. Пример приведен ниже.

HandlerThread handlerThread = new HandlerThread("NoiceHandlerThread"); 
handlerThread.start(); 
Handler handler = new Handler(handlerThread.getLooper()); 
+0

будет работать, даже если приложение будет сведено к минимуму? Я использовал сервис, потому что он остается активным даже тогда, когда приложение не находится на экране. –

+0

есть. вы можете использовать сервис. то он все равно будет работать, даже если приложение не находится на переднем плане. –

+0

большое спасибо –

1

postDelayed() - отличное решение для Service. Как вы заметили, он привязан к основному потоку приложения, и обычно мы хотим, чтобы службы не выполняли работу по основной теме приложения.

Использовать другие стандартные механизмы синхронизации Java, like ScheduledExecutorService.

+0

спасибо, но не могли бы вы привести краткий пример? –

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