Android重复服务 - onCreate调用一次,onStartCommand调用许多

时间:2016-01-28 07:18:46

标签: android android-service locationmanager

我按照基本的android文档来实现Service,每隔40秒由AlarmManager重复触发。在服务中我注册了GPS听众,如果我在30秒内没有得到修复,我会拨打stopSelf(),这是为了避免2"并发"服务一起运行。但是如果我确实在不到30秒的时间内完成了修复,我会执行一些逻辑,在完成之后我会调用stopSelf() - 假设一切都需要不到40秒,所以我再也没有问题"并发&# 34;服务运行...

当我记录打印各种服务方法的执行顺序时,它没有任何意义:

  1. onCreate仅被调用一次,而onStartCommand每40秒触发一次。
  2. GPS永远不会被修复,也许托管Activity也注册并确实有GPS修复干扰了这一事实? (我在户外测试,活动确实得到修复)
  3. 这是我的实现 - 非常简单的googles android文档:

    public class DirectionService extends Service implements Constants {
    
    private LocationManager mLocationManager;
    private LocationListener mLocationListeners;
    private Context mContext;
    private Looper mServiceLooper;
    private ServiceHandler mServiceHandler;
    
    @Override
    public IBinder onBind(Intent arg0) {
        return null;  //not binding
    }
    
    @Override
    public void onCreate() {
        HandlerThread thread = new HandlerThread("ServiceStartArguments", Process.THREAD_PRIORITY_BACKGROUND);
        thread.start();
        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);
        mContext = getApplicationContext();
    }
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        //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);
        return START_STICKY;
    }
    
    //Handler that receives messages from the thread
    private final class ServiceHandler extends Handler {
    
        public ServiceHandler(Looper looper) {
            super(looper);
        }
    
        /**
         * The real work done after we have (first) fixed location and from there we stop the service.
         * Therefore we pass the start id.
         */
        @Override
        public void handleMessage(final Message msg) {
            if (mLocationManager == null) {
                mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
                mLocationListeners = new LocationListener(msg.arg1);
            }
            try {
                mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, GPS_UPDATE_TIME, 0, mLocationListeners);
                mLocationManager.addGpsStatusListener(mGPSStatusListener);
            } catch (Exception e) {
                stopSelf(msg.arg1);
            }
            //Start timer for GPS to get fix location. Else we might have new concurrent instance of service
            new CountDownTimer(30000, 15000) {
    
                public void onTick(long millisUntilFinished) {}
    
                public void onFinish() {
                    stopSelf(msg.arg1);
                }
    
            }.start();
        }
    
    }
    
    GpsStatus.Listener mGPSStatusListener = new GpsStatus.Listener() {
        public void onGpsStatusChanged(int event) {
            switch (event)
            {
                case GpsStatus.GPS_EVENT_FIRST_FIX:
                    if (ContextCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
                            || ContextCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                        if (mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER) != null) {
                            isGpsFixed = true;
                        }
                    }
                    break;
                default:
                    break;
            }
        }
    };
    
    private class LocationListener implements android.location.LocationListener {
    
        private int startId;
    
        public LocationListener(int startId) {
            this.startId = startId;
        }
    
        @Override
        public void onLocationChanged(Location location) {
            if (isGpsFixed == true && location.getLongitude() != 0.0 && location.getLatitude() != 0.0 && isAlreadySentToCheck == false) {
                isAlreadySentToCheck = true;
                startLogic(startId);
            }
        }
        @Override
        public void onProviderDisabled(String provider) {}
        @Override
        public void onProviderEnabled(String provider) {}
        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {}
    }
    
    private void startLogic(final int startId) {
        //...
        stopSelf(startId);
    }
    
    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mLocationManager != null) {
            try {
                mLocationManager.removeUpdates(mLocationListeners);
            } catch (Exception ex) {}
        }
    }
    

1 个答案:

答案 0 :(得分:1)

由于start_sticky

,您的服务运行了很多次

如果您的服务由于内存不足而被Android杀死,Android会清除一些内存,那么......

STICKY:... Android将重新启动您的服务,因为该特定标志已设置。

NOT_STICKY:... Android不会关心重新开始,因为该标志告诉Android它不应该打扰。

REDELIVER_INTENT:... Android将重新启动服务并将相同的意图重新发送到该服务的onStartCommand(),因为该标志也是如此。

建议你的start_not_sticky