2016-01-28 5 views
0

Я выполнил базовую документацию по Android для реализации Service, вызванную повторно на AlarmManager каждые 40 секунд. Внутри службы я регистрирую приемник GPS, и если я не получу исправления в течение 30 секунд, я звоню stopSelf(), чтобы избежать использования двух «параллельных» сервисов. Однако, если у меня есть исправление в течение менее 30 секунд, я выполняю некоторую логику, и после этого я позвонил stopSelf(). Предполагая, что все это займет менее 40 секунд, так что у меня нет проблем с «параллельными» службами ...Android-повторный сервис - onCreate, вызываемый один раз, onStartCommand вызвал много

При входе печати порядок выполнения различных методов обслуживания не имеет никакого смысла:

  1. onCreate вызывается только один раз, в то время как onStartCommand срабатывает каждые 40 секунд.
  2. GPS никогда не фиксируется, может быть, тот факт, что хостинг Activity также зарегистрирован и у него есть помеха GPS здесь? (Я тестирование на открытом воздухе и деятельность действительно получает исправление)

Это моя реализация - Довольно много прямолинейный Googles андроид документации:

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

Услуга - это одноэлементный класс. только один экземпляр данной службы будет работать в любой момент времени. Вам не нужно усложнять свою логику. Если вызов выполняется уже запущенной службой, то будет вызываться ** onStartCommand() **. Вот почему вы получаете повторяющиеся триггеры этого метода. – SoulRayder

ответ

1

вашей служба работает много времени из-за start_sticky

если ваш сервис убит Android из-за низкой памяти, а Android очищает некоторую память, затем ...

STICKY: ... Android перезапустит ваш сервис, потому что этот особый флаг s и др.

NOT_STICKY: ... Android не будет заботиться о том, чтобы снова начать, потому что флаг сообщает Android, что он не должен беспокоить.

REDELIVER_INTENT: ... Android перезапустит службу и повторно добавит то же самое намерение к службе onStartCommand() службы, потому что снова флаг.

предлагаю начать start_not_sticky

+0

Итак, на самом деле вы предлагаете мое служение, всегда убитое ОС ... Как насчет приемника GPS? Должны быть проблемы? – michael

Смежные вопросы