2016-05-26 6 views
-1

Ich habe einen Handler, der sich in einem Service befindet, und ich blockiere diesen Thread, bis der Benutzer den Dienst beendet. Um es weniger CPU-intensiv zu machen, versuche ich Thread.sleep() zu benutzen und wiederhole die Blockierungsbedingung nach einem Intervall von 10 minutes. Hier ist meine Umsetzung meines handlemessage:Wie sende ich einen Interrupt an einen Handler, um eine Thread.sleep() zu brechen?

@Override 
public void handleMessage(Message msg) { 
    Log.e("Service", "looper started"); 
    GPSThread gp=new GPSThread(getApplicationContext()); 
    gp.start();   
    ModeController mc=new ModeController(getApplicationContext()); 
    mc.start(); 
    NetworkSniffer nh=new NetworkSniffer(getApplicationContext()); 
    nh.start(); 
    while(stopService) //stopService is a volatile boolean i use to block until user opts to stop the service 
    {     
     try { 
      Thread.sleep(10*60*1000); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
       e.printStackTrace(); 
     }    
    }  
    mc.stopThread(); 
    gp.stopThread(); 
    nh.stopNetworkThread(); 
    stopSelf(msg.arg1); 
} 

Nun mein Problem ist, dass wenn ich den Wert von Stopservice auf false ändern (durch eine öffentliche Funktion) könnte es bis zu 10 Minuten dauern, die while-Schleife zu beenden. Wenn es ein Thread wäre, hätte ich eine Thread.interrupt() verwendet und die While-Schleife beendet.

Also meine Frage ist, wie erreiche ich eine ähnliche Sache für Handler, d. H., Wie eine InterruptedException für Thread.sleep() in einem Handler zu werfen.

Antwort

1

Wenn es ein Thread wäre, hätte ich eine Thread.interrupt() verwendet und die While-Schleife beendet.

Eigentlich ist der Code >> ist < < auf einem Thread ausgeführt wird, so dass Sie, wenn Sie trainieren könnte, was das Gewinde ist, könnten Sie es unterbrechen.

Setzen Sie das beiseite, die Art, die Sie dies tun sollten, ist, den Code zu haben, wo Sie versucht hätten, den Thread-Aufruf Service.stopService zu unterbrechen.

Referenzen:

Dieser Ansatz funktioniert, wenn der Thread, der Handler-Thread den Dienst des schläft. Wenn Sie den Thread explizit selbst erstellt haben, müssen Sie den von uns erstellten Thread im Auge behalten und Thread.interrupt darauf verwenden. (Und man konnte den Thread.interrupted Zustand eher als ein benutzerdefinierten stopService Flag verwenden.)

jedoch eine bessere Idee wäre, die sleep Schleife zu vermeiden: https://stackoverflow.com/a/845291/139985

+0

Vielen Dank für die Links Herr, ich gehe durch sie. Ich habe nur eine Sache nicht bekommen. Du hast gesagt, wenn ich den Thread ausarbeiten könnte, könnte ich einen Interrupt darauf ansetzen. Wie kann ich den Thread Sir erarbeiten? –

+0

Es wäre wahrscheinlich schwierig. (In der klassischen Java-Welt würden Sie wahrscheinlich die ThreadGroup-Hierarchie verwenden und den Thread nach dem Namen suchen. Aber das ist eine schlechte Idee.) Wenn Sie serviceStop nicht verwenden können, ist es am besten, die Thread-Referenz in einer Variablen zu speichern ... –

+0

Danke Sir, endlich hat es funktioniert. Ich habe die Thread-Instanz vom HandlerThread-Objekt, das ich HandlerThread thread = new HandlerThread ("ServiceStartArguments", Process.THREAD_PRIORITY_BACKGROUND) verwende; '. Schließlich habe ich einen Interrupt für diese Threadvariable in 'stopServiceMethod()' aufgerufen. –

1

Dank @Stephen C schließlich bekam sie zu arbeiten. Veröffentlichen Sie meinen Code in der Hoffnung, dass es anderen in Zukunft helfen könnte:

package com.example.userpc.roadtracker; 


import android.app.Service; 
import android.content.Intent; 
import android.os.Handler; 
import android.os.HandlerThread; 
import android.os.IBinder; 
import android.os.Looper; 
import android.os.Message; 
import android.os.Process; 
import android.util.Log; 

/** 
* Created by USER PC on 5/21/2016. 
*/ 
public class MainServiceThread extends Service { 

    private Looper mServiceLooper; 
    private ServiceHandler mServiceHandler; 
    private volatile static boolean stopService=true; 
    private static HandlerThread mThread; 

    public static void stopServiceThread() 
    { 
     stopService=false; 
     mThread.interrupt(); 
    } 

    private final class ServiceHandler extends Handler { 
     public ServiceHandler(Looper looper) { 
      super(looper); 
     } 
     @Override 
     public void handleMessage(Message msg) { 
      Log.e("Service", "looper started"); 
      GPSThread gp=new GPSThread(getApplicationContext()); 
      gp.start();   
      ModeController mc=new ModeController(getApplicationContext()); 
      mc.start(); 
      NetworkSniffer nh=new NetworkSniffer(getApplicationContext()); 
      nh.start(); 
      while(stopService) 
      {     
       try { 
        Thread.sleep(10*60*1000); 

       } catch (InterruptedException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       }    
      }  
      mc.stopThread(); 
      gp.stopThread(); 
      nh.stopNetworkThread(); 
      stopSelf(msg.arg1); 
     } 
    } 

    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 

    @Override 
    public void onCreate() { 
     Log.e("Service", "in onCreate"); 
     stopService=true; 
     HandlerThread thread = new HandlerThread("ServiceStartArguments", 
       Process.THREAD_PRIORITY_BACKGROUND); 
     mThread=thread; 
     thread.start(); 
     mServiceLooper = thread.getLooper(); 
     mServiceHandler = new ServiceHandler(mServiceLooper); 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     Log.e("Service","Started"); 
     Message msg = mServiceHandler.obtainMessage(); 
     msg.arg1 = startId; 
     mServiceHandler.sendMessage(msg); 
     return START_STICKY; 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     mThread=null; 
     Log.e("Service","Destroyed"); 
    } 


} 
Verwandte Themen