开发者

Android service continues to run after force stop

开发者 https://www.devze.com 2023-02-21 02:45 出处:网络
I have a Service that spawns a Thread to connect to a third-party and it runs fine.However, if I go to settings and stop the service, it continues to run.It disappears from the Running Services in set

I have a Service that spawns a Thread to connect to a third-party and it runs fine. However, if I go to settings and stop the service, it continues to run. It disappears from the Running Services in settings and the onDestroy method is called, but I still see each method in the Service being called. I'm assuming that I'm not using the Thread correctly, but I don't see why the service would continue running... unless it keeps running until all of the threads are done.

public class DataProcessorService extends Service {

    private ServiceState _state;
    private ConnectThread _connectThread;

    private Handler _handler = new Handler() {
        public synchronized void handleMessage(Message msg) {
            stopConnectThread();
            onNextState();  // Goes to state开发者_C百科 after Connecting
        }
    };

    @Override
    public void onCreate() {
        logger.debug("onCreate called");

        _state = ServiceState.readState(this);

        switch (_state) {
        ...
        case CONNECTING:
            onConnecting();
            break;
        ...
        }
    }

    @Override
    public void onDestroy() {
        logger.debug("onDestroy called");
        stopConnectThread();
        ServiceState.saveState(this, _state);
    }

    private void onConnecting() {
        _state = ServiceState.CONNECTING;
        logger.debug("onConnecting called");

        _connectThread = new ConnectThread(this, _handler);
        _connectThread.setDaemon(true);
        _connectThread.start();
    }

    private void stopConnectThread() {
        if (_connectThread != null) {
            _connectThread.interrupt();
            _connectThread = null;
        }
    }
}

Here's my ConnectThread class (I also tried doing what was suggested here which is the commented sections):

public class ConnectThread extends Thread {

    private final Context _context;
    private final Handler _handler;

//    private volatile Thread runner;

    public ConnectThread(Context context, Handler handler) {
        super("ConnectThread");
        this._context = context;
        this._handler = handler;
    }

//    public synchronized void startThread() {
//        if (runner == null) {
//            runner = new Thread(this);
//            runner.start();
//        }
//    }
//
//    public synchronized void stopThread() {
//        if (runner != null) {
//            Thread moribund = runner;
//            runner = null;
//            moribund.interrupt();
//        }
//    }

    @Override
    public void run() {
        Looper.prepare();
//        if (Thread.currentThread() == runner) {
            logger.debug("Service started");

            Thread.sleep(5000); //inside try-catch
//        }
        Looper.loop();
    }

}

When I look in DDMS, it shows multiple ConnectThreads and they're each in the wait status, so I'm assuming they're finishing and not being killed and that may be preventing my Service from stopping. Does anyone see why the issue is happening, or know how to fix it?

EDIT: I'm now starting to think it may be because I need a Looper.quit() call somewhere. I'll need to read up on Looper and Handler more. I started to look at HandlerThread but I'm not real clear on what Loopers are for, yet. Is passing a Handler to my ConnectThread a bad idea?


You have to stop the Looper from looping in stopConnectThread(). Just interrupting the Thread doesn't won't stop the Looper. Try this:

in ConnectThread class add:

private Looper myLooper; // A reference to the Looper for this Thread
public void stopLooper() {
    // Tell Looper to stop looping
    myLooper.quit();
}

in ConnectThread.run() method, after Looper.prepare() add:

myLooper = Looper.myLooper(); // Get the Looper associated with this Thread

in stopConnectThread(), instead of _connectThread.interrupt(); do this:

_connectThread.stopLooper();
0

精彩评论

暂无评论...
验证码 换一张
取 消