此代码位于可穿戴设备上。我需要使用自定义构造函数创建服务(我需要传递另一个上下文)。所以我用这种方式创建并启动了服务:
更新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();
}
}
答案 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);
如果有这项工作,请告诉我。