2013-12-05 14 views
1

Я создал ListView. Каждый из элементов ListView содержит ToggleButton, , который запускает или останавливает поток в службе.Служба Android с несколькими темами

Нити должны работать до тех пор, пока активируются кнопки toggleButtons. Если действие прекращается, служба и активированные потоки должны быть продолжены.

//In MainActivity 
@Override 
public void onCheckedChanged(CompoundButton buttonView, 
       boolean isChecked) { 
Intent intent = new Intent(context,MyService.class); 
intent.putExtra("id",listviewPosition); 
startService(intent); 
} 


//MyService 
@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    // Thread(startId) starten 
    HandlerThread thread = new HandlerThread(String.valueOf(startId)); 
    thread.start(); 
    // Threads looper holen und beim servicehandler benutzen 
    serviceHandler = new ServiceHandler(thread.getLooper()); 
    listServericeHandler.add(serviceHandler); 
    //message ausm pool holen 
    Message msg = serviceHandler.obtainMessage(); 
    msg.arg1 = startId; 
    serviceHandler.sendMessage(msg); 
    return START_STICKY; 
} 

private final class ServiceHandler extends Handler { 
public ServiceHandler(Looper looper) { 
    super(looper); 
    } 

@Override 
public void handleMessage(Message msg) { 
while (continueUntilToggleButtonIsDeactivated) { 
Log.d(MainActivity.TAG, "Thread " + tring.valueOf(msg.arg1) 
       + " running: " + url.toExternalForm()); 
synchronized (this) { 
     try { 
      //do stuff 
      wait(1000); 
     } catch (Exception e) { 
     } 
     } 
    } 
} 
} 

Итак, я пытаюсь начать нить в OnStartCommand() каждый раз, когда я активировать ToggleButton.

Что я не знаю, так это то, как остановить потоки и выйти из цикла while.

+0

В декларации времени цикла является 'continueUntilToggleButtonIsDeactivated' переменного, или просто ваше объяснения? Если это переменная, то где вы ее устанавливаете? – RocketSpock

+0

Это должно быть какое-то объяснение. im попытался установить переменную при вызове onCheckedChanged, но я не могу обрабатывать несколько потоков таким образом. – MaffelBaffel

+0

^Нужна эта информация, чтобы помочь. Как вы обрабатываете флаг 'continueUntilToggleButtonIsDeactivated'. Установите его на false, когда вы остановите поток –

ответ

0

Вам просто нужно создать флаг для цикла while, чтобы знать, когда остановиться. Например:

private final class ServiceHandler extends Handler { 
    private volatile boolean _continueRunning = true; 

    public ServiceHandler(Looper looper) { 
     super(looper); 
    } 

    public void stopRunning() { 
     _continueRunning = false; 
     this.notify(); //Interrupts the wait 
    } 

    @Override 
    public void handleMessage(Message msg) { 
     while (_continueRunning) { //Watches the variable 
      Log.d(MainActivity.TAG, "Thread " + tring.valueOf(msg.arg1) 
           + " running: " + url.toExternalForm()); 

     synchronized (this) { 
      try { 
       //do stuff 
       wait(1000); 
      } catch (Exception e) {} 
     } 
    } 
} 

EDIT

Вы должны создать свой обработчик в onCreate() методе обслуживания. Метод onStartCommand информирует вас о новых сообщениях.

//In your Service Class 
... 
private ServiceHandler _serviceHandler; 

@Override 
public void onCreate() { 
    HandlerThread thread = new HandlerThread("ServiceClassName"); 
    thread.start(); 

    // Threads looper holen und beim servicehandler benutzen 
    serviceHandler = new ServiceHandler(thread.getLooper()); 
} 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    //message ausm pool holen 
    Message msg = _serviceHandler.obtainMessage(); 
    msg.arg1 = startId; 
    serviceHandler.sendMessage(msg); 
    return START_STICKY; 
} 

private class mRunnable implements Runnable { 
    private volatile boolean _continueRunning = true; 

    @Override 
    public void run() { 
     while (_continueRunning) { //Watches the variable 
      synchronized (this) { 
       try { 
        //do stuff 
        wait(1000); 
       } catch (Exception e) { 
        //Purposefully left blank 
       } 
      } 
     } 
    } 

    public void stopRunning() { 
     _continueRunning = false; 
     this.notify(); 
    } 
} 

Затем вы меняете ServiceHandler к

private final class ServiceHandler extends Handler { 
    //TODO whatever type of list you need 
    private List<mRunnable> _runningThreads = new LinkedList<mRunnable>(); 

    public ServiceHandler(Looper looper) { 
     super(looper); 
    } 

    @Override 
    public void handleMessage(Message msg) { 
     mRunnable runnable = new mRunnable(); 
     new Thread(runnable).start(); 
    } 
} 
+0

Ну, я вижу, как вы справлялись с этим, но я до сих пор не знаю, как я получаю несколько потоков, работающих таким образом. Служба останавливается, если я останавливаю один поток, и если выполняется второй поток, я получаю nullpointerexception после вызова stopRunning(). Вызывает onStartCommand() правильный способ запуска нового потока? – MaffelBaffel

+0

ok нашел мое недоразумение. Решение принято :) Спасибо! – MaffelBaffel

+0

Ха-ха. Пожалуйста. Я также обновил другой способ сделать это (так как я, видимо, не заметил, что ваше замечание заранее). – RocketSpock

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