2016-07-19 23 views
2

Ich möchte, dass meine Funktion aufzurufen alle 10 Sekunden mit einem Timer und meine Funktion ein Handler hat es zeigt einen Fehler:Android Call-Methode alle 10 Sekunden mit Handler

java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

Meine Funktion:

public void startData(){ 
doBindService(); 
new Handler().post(mQueueCommands); 
} 

diese startData() hat eine öffentliche Variable "btIsConnected", immer wenn btIsConnected== true, ich möchte aufhören zu rufen, sonst für die ersten zwei Minuten möchte ich startData() alle 10 Sekunden

aufrufen
class startLiveDataTimerTask extends TimerTask{ 
    public void run(){ 
     startData(); 
    } 
} 

private void tryConnectEveryTenSeconds() { 
    Timer timer = new Timer(); 
    timer.schedule(new startLiveDataTimerTask(), 0, 10000); 
} 

in onCreate():

long futureTimeInTwoMinute = System.currentTimeMillis() + 120000; 

Intent i = new Intent(ObdConstants.StartLiveData.getValue()); sendBroadcast(i); // this broadcaster is used to call StartData() for the first time 

    if(System.currentTimeMillis()<futureTimeInTwoMinute){ 
// how do I make a time counter appropriately? 
     if(btIsConnected){ 
      Log.d(TAG, "is connected!"); 
      //do nothing 
     }else{ 
      Log.d(TAG, "try to connect every ten seconds...."); 
      tryConnectEveryTenSeconds(); 
     } 
    } 

Antwort

2

Wenn Sie die Handler-Architektur verwenden möchten, wird das Objekt Timer nicht verwendet.

Zuerst erhalten Sie den Handler. Für das Beispiel werde ich die Haupt-Handler (UIThread) verwenden, aber Sie können auch Ihre eigenen erstellen, mit einem neuen Looper.

So lässt die geschleift Aufgabe wie folgt beginnen:

private void tryConnectEveryTenSeconds() { 
    Handler handler = new Handler(Looper.getMainLooper()); //This gets the UIThread Handler 
    handler.postDelayed(new startLiveDataTimerTask(), 10000); //This posts the task ONCE, with 10 sec delay 
} 

Und nun die Aufgabe:

public void startData(){ 
    doBindService(); 
    Handler handler = new Handler(Looper.getMainLooper()); 
    handler.post(mQueueCommands); //I expect this is what you want. If not and you want a completely new Handler, you will need to create it on a new Thread 
    handler.postDelayed(new startLiveDataTimerTask(), 10000); //This posts the task AGAIN, with 10 seconds delay  
} 

Bitte beachten Sie, dass alle Methoden auf dem UIThread aufgerufen werden. Wenn Sie möchten, dass die mQueueCommands-Task in einem neuen Thread unter einem neuen Handler ausgeführt wird, müssen Sie sie erstellen.


EDIT:

Der rufenden Code wie folgt aussehen sollte:

long futureTimeInTwoMinute = System.currentTimeMillis() + 120000; 

Intent i = new Intent(ObdConstants.StartLiveData.getValue()); sendBroadcast(i); 
tryConnectEveryTenSeconds(); 
while(System.currentTimeMillis()<futureTimeInTwoMinute){ 
    if(btIsConnected){ 
     Log.d(TAG, "is connected!"); 
     //do nothing 
    }else{ 
     Log.d(TAG, "Not connected yet..."); 
    } 
} 

Sie wollen nicht die Looping-Verfahren mehr schießen als einmal :-)

+0

Hallo danke für Ihre Hilfe! Nachdem ich den Code geändert habe, funktionierte es, aber ich fand, dass startData() wiederholt alle 50 oder 100 Millisekunden aufgerufen wird ... weißt du warum? – Deidara

+0

Wie rufen Sie die tryConnectEveryTenSeconds() -Methode auf? – Kelevandos

+0

Ich denke, ich muss mehr Details hinzufügen, also habe ich meinen Beitrag aktualisiert. Vielen Dank! – Deidara

1

Handlers kann nur auf Threads erstellt werden, die in einem Looper sind. Der Haupt-UI-Thread befindet sich in einem Looper, sodass Handler dort erstellt werden können. Ein normaler Thread oder eine asyncTask ist das nicht, daher können sie keine Handler erstellen. Angenommen, Sie möchten auf dem UI-Thread posten, müssen Sie den Handler im UI-Thread erstellen.

Nebenbei ist es sehr ungewöhnlich, Code zu sehen, der einen neuen Handler so erzeugt. Im Allgemeinen besteht das Muster darin, einen einzelnen Handler in Ihrem Konstruktor zu erstellen und darauf zu posten. Das Erstellen neuer Handler ist im besten Fall ineffizient und im schlimmsten Fall ein Fehler.