Following Googles examples for using a Service, I created a couple of threads like this. I can't use IntentService, because I'm doing something that involves waiting for callbacks.
However, I don't know how to terminate a Thread started in this manner. As I understand it, Threads automatically terminate when the run() method returns. However, this kind of thread doesn't have a run method. My Threads are leaking--they stay alive after stopSelf().
@Override
public void onCreate() {
HandlerThread thread = new HandlerThread("ServiceStartArguments",
android.os.Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
HandlerThread thread2 = new HandlerThread("CallbackHandling",
android.os.Process.THREAD_PRIORITY_BACKGROUND);
thread2.start();
mServiceLooper = thread.getLooper();
mCallbackLooper = thread2.getLooper();
mServiceHandler = new MyHandler(mServiceLooper);
mCallbackHandler = new Handler(mCallbackLooper);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
// For each start request, send a message to start a job and deliver the
// start ID so we know which request we're stopping when we finish the job
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
mServiceHandler.sendMessage(msg);
mMainThreadHandler=new Handler();
// If we get killed, after returning from here, restart
return START_STICKY;
}
private final class MyHandler extends Handler {
public MyHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
cycle();
// Stop the service using the startId, so that we don't stop
// the service in the middle of handling another job
stopSelf(msg.arg1);
}
}
protected void cycle() {
...
mCallbackHandler.post(new Runnable(){
public void run(){
goAskForSomeCallbacks();
}
});
try {
Thread.sleep(GIVE_UP_TIME);
} catch (InterruptedException e){
//The callback will interrupt this thread to stop it from waiting
Log.d(TAG,"Got early callback, stop waiting.");
}
Thread.interrupted(); //clear the interrupt
doStuff();
}
android.os.HandlerThread. A Thread that has a Looper . The Looper can then be used to create Handler s. Note that just like with a regular Thread , Thread. start() must still be called.
When you use new Thread(r). start() , you actually created a new thread and run task asynchronously. When you use new Handler(). post(r) (or Message ), you added the Runnable object to Looper and execute the code later in the same thread.
You can also use the following recommended approach:
but be careful before using it because it cancels all pending jobs
handler.quitSafely();
Try calling the quit
method on the corresponding Loopers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With