Android,调用stopSelf()不会停止服务

时间:2014-07-28 05:47:59

标签: android android-service

此代码位于可穿戴设备上。我需要使用自定义构造函数创建服务(我需要传递另一个上下文)。所以我用这种方式创建并启动了服务:

更新2 此部分位于调用活动(WearActivity)的onCreate()中。

Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            HeartRateMonitorService service = new HeartRateMonitorService(WearActivity.this);
            service.onCreate();
            service.onStartCommand(null,0,123);
        }
    }, 5000);

然后在onStartCommand函数中,我发布了一个延迟Runnable,以便stopSelf停止服务。

 @Override
public int onStartCommand(Intent intent, int flags, int startId) {
    int superResult = super.onStartCommand(intent, flags, startId);
    //...other code
    Handler handler = new Handler();
    handler.postDelayed( stopServiceRunnable
    , EXPIRY_TIME_IN_MILLIS);
    return START_NOT_STICKY;
}

Runnable stopServiceRunnable = new Runnable() {
    @Override
    public void run() {
        Log.d(TAG, "calling stopSelf()");
        stopSelf();
    }
};

代码确实跳转到Runnable内部(通过打印出日志行),但是,它没有跳转到onDestroy()。此外,服务中的其他任务继续执行和打印日志(它是心率监视服务)。

有什么想法吗?感谢。

更新:完整的源代码文件,根据需要:

package com.marctan.hrmtest;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;

import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.wearable.MessageApi;
import com.google.android.gms.wearable.Node;
import com.google.android.gms.wearable.NodeApi;
import com.google.android.gms.wearable.Wearable;
import com.google.android.gms.wearable.WearableStatusCodes;

import java.util.Iterator;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentLinkedQueue;

public class HeartRateMonitorService extends Service implements SensorEventListener {

    private static final String TAG = "HRService";

    private Sensor mHeartRateSensor;
    private SensorManager mSensorManager;
//    private CountDownLatch latch;
    private static final int SENSOR_TYPE_HEARTRATE = 65562;

    private int mStartId;

    private static final String PATH = "MyHeart";

    TimerTask timerTask;
    private long mStartTime;

    public static final long EXPIRY_TIME_IN_MILLIS = TimeUtils.InMillis.SECOND *20;

    private static final long INTERVAL_TO_CHECK_CONNECTION_MILLIS = 3000 ;

    GoogleApiClient googleApiClient;

    Context mBaseConext;
    private Timer mTimer;

    ConcurrentLinkedQueue<HeartRate> queue;

    public HeartRateMonitorService(Context context){
        super();
        mBaseConext = context;
    }

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

    @Override
    public void onCreate() {
        super.onCreate();
        attachBaseContext(mBaseConext);
        queue = new ConcurrentLinkedQueue<HeartRate>();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        int superResult = super.onStartCommand(intent, flags, startId);
        mStartId = startId;
        Log.d(TAG, "prepare to call getSystemService");

        mSensorManager = ((SensorManager)mBaseConext.getSystemService(SENSOR_SERVICE));
        Log.d(TAG, "after calling getSystemService");
        mHeartRateSensor = mSensorManager.getDefaultSensor(SENSOR_TYPE_HEARTRATE); // using Sensor Lib2 (Samsung Gear Live)
        mSensorManager.registerListener(HeartRateMonitorService.this, mHeartRateSensor, 3);


        mStartTime = System.currentTimeMillis();



        googleApiClient = new GoogleApiClient.Builder(HeartRateMonitorService.this)
                .addApi(Wearable.API)
                .build();

        googleApiClient.connect();
        startActiveStateCheckingTimer();
        Handler handler = new Handler();
        handler.postDelayed( stopServiceRunnable
        , EXPIRY_TIME_IN_MILLIS);

        return START_NOT_STICKY;
    }

    /***/
    private void startActiveStateCheckingTimer() {
        if (mTimer == null) {
            mTimer = new Timer();

            timerTask = new CheckTask();
            mTimer.scheduleAtFixedRate(timerTask, 0,
                    INTERVAL_TO_CHECK_CONNECTION_MILLIS);
        }

    }

    Runnable stopServiceRunnable = new Runnable() {
        @Override
        public void run() {
            mSensorManager.unregisterListener(HeartRateMonitorService.this);
            Log.d(TAG, "calling stopSelf()");
            stopSelf();
        }
    };

    private class CheckTask extends TimerTask{
        int localCount=0;
        @Override
        public void run() {
            Log.d("SHORT_IN","count: "+ localCount );
            fireMessageSimple();
            localCount++;

        }
    }

    public static class HeartRate {
        private final int accuracy;
        final int rate;
        final long signature;

        public HeartRate(int rate, long _sign, int accuracy) {
            this.rate = rate;
            this.signature= _sign;
            this.accuracy = accuracy;
        }
    }


    @Override
    public void onSensorChanged(SensorEvent sensorEvent) {
        //should get the time outside the queuing task to be precise
        long timeStampMillis = System.currentTimeMillis();
        QueuingTask task = new QueuingTask(queue,timeStampMillis, sensorEvent);
        task.execute();
    }

    private void fireMessageSimple() {
        // Send the RPC
        PendingResult<NodeApi.GetConnectedNodesResult> nodes = Wearable.NodeApi.getConnectedNodes(googleApiClient);
        nodes.setResultCallback(new ResultCallback<NodeApi.GetConnectedNodesResult>() {
            @Override
            public void onResult(NodeApi.GetConnectedNodesResult result) {
                for (int i = 0; i < result.getNodes().size(); i++) {
                    Node node = result.getNodes().get(i);
                    String nName = node.getDisplayName();
                    String nId = node.getId();
                    Log.d(TAG, "Node name and ID: " + nName + " | " + nId);
                    byte [] myBytes;
                    StringBuilder sBuidler = new StringBuilder();
                    Iterator<HeartRate> iter = queue.iterator();
                    int count=0;
                    while (iter.hasNext() && count <100 ){
                        HeartRate rate = iter.next();
                        sBuidler.append(rate.signature).append(",").append(rate.accuracy).append(",").append(rate.rate).append("\n");
                        iter.remove();
                        count++;
                    }
                    myBytes = sBuidler.toString().getBytes();


                    PendingResult<MessageApi.SendMessageResult> messageResult = Wearable.MessageApi.sendMessage(googleApiClient, node.getId(),
                            PATH, myBytes);
                    messageResult.setResultCallback(new ResultCallback<MessageApi.SendMessageResult>() {
                        @Override
                        public void onResult(MessageApi.SendMessageResult sendMessageResult) {
                            Status status = sendMessageResult.getStatus();
                            Log.d(TAG, "Status: " + status.toString());
                            if (status.getStatusCode() == WearableStatusCodes.SUCCESS) {
                                Log.d(TAG, "SENT SUCCESSFULLY !!!!!!!!!!!!!");

                            }
                        }
                    });
                }
            }
        });
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int i) {
        Log.d(TAG, "accuracy changed: " + i);
    }

    @Override
    public void onDestroy() {
        Log.d(TAG, "calling onDestroy");
        Log.d(TAG, "calling onDestroy");
        Log.d(TAG, "calling onDestroy");
        Log.d(TAG, "calling onDestroy");
        Log.d(TAG, "calling onDestroy");
        Log.d(TAG, "calling onDestroy");
        Log.d(TAG, "calling onDestroy");
        Log.d(TAG, "calling onDestroy");
        Log.d(TAG, "calling onDestroy");
        Log.d(TAG, "calling onDestroy");
        Log.d(TAG, "calling onDestroy");
        Log.d(TAG, "calling onDestroy");
        Log.d(TAG, "calling onDestroy");
        Log.d(TAG, "calling onDestroy");
        Log.d(TAG, "calling onDestroy");
        Log.d(TAG, "calling onDestroy");
        Log.d(TAG, "calling onDestroy");
        Log.d(TAG, "calling onDestroy");
        Log.d(TAG, "calling onDestroy");
        super.onDestroy();
    }
}

1 个答案:

答案 0 :(得分:0)

只是提示,而不是使用runnable尝试使用asyncTask,如下所示

 public class StopServiceTask extends AsyncTask<Void, Void, Void> {

    @Override
    protected Void doInBackground(final Void... params) {
        try {
            Thread.sleep(EXPIRY_TIME_IN_MILLIS);
        } catch (final InterruptedException e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    protected void onPostExecute(final Void result) {
        Log.d(TAG, "calling stopSelf()");
        stopSelf();
    }

 }

并将其调用到您当前正在运行可运行的

的位置
 new StopServiceTask()
            .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

如果有这项工作,请告诉我。