stopService不会停止我的服务....为什么?

时间:2010-12-17 12:25:10

标签: android service

我在我的Android APP上有一个后台服务,它正在获取我的GPS位置并将其发送到远程数据库。它工作得很好。

问题是当我想要停止服务时....它不会停止:S。此外,没有出现例外或logcat上的错误......它根本不会停止。

这是启动我的srvice的代码(带按钮):

startService(new Intent(GPSLoc.this, MyService.class)); //enciendo el service

这是我停止它的代码(在onactivityresult方法上):

stopService(new Intent(GPSLoc.this, MyService.class));

我已经调试了应用程序,并且我检查了每次调试时都调用了stopService代码行,但它没有停止......

我确信它没有停止导致我的数据库因为我按下按钮停止服务时仍然从模拟器中恢复gps位置。

我做得不好?

11 个答案:

答案 0 :(得分:32)

您是否已实施onDestroy()?如果没有,我相信这可能是解决方案 - 您可以停止Timer或其他任何用于在onDestroy()内运行服务的内容。

  

可以通过调用stopSelf()方法或调用Context.stopService()来停止服务。

有关更多信息,请参阅此link

答案 1 :(得分:9)

  

我确信它没有停止导致我的数据库因为我按下按钮停止服务时仍然从模拟器中恢复gps位置。

您可能没有取消注册LocationListener

答案 2 :(得分:4)

我遇到了同样的问题。我发现,如果服务已连接GoogleApiClient且仍然获得位置更新,stopService()完全没有效果,则不会调用服务的行业()。 为了解决这个问题,我创建了一个函数来停止服务代码中的位置服务。从活动中调用stopLocationService(),然后调用stopService。这是代码示例:

public class myLocationService extends Service{
...

    public void stopLocationUpdates() {

        LocationService.FusedLocationApi.removeLocationUpdates(mGoogleApiClient,this);       
        mGoogleApiClient.disconnect();

    }
    ...
} 

在活动中,

{
    ...
    if(mService != null && isBound) {

        mService.stopLocationUpdates();
        doUnbindService();
        stopService(new Intent(this,   myLocationService.class));

     }
     ...
} 

答案 3 :(得分:2)

这种情况非常常见,我需要在完成此过程之前停止我的服务。在某些情况下,使用stopService(intent)是不够的。您应该记住我的服务中的onDestroy()实现。例如:

public class MyIntentService extends IntentService {

    // Defines and instantiates an object for handling status updates.
    private BroadcastNotifier mBroadcaster = null;
    private int progress = 0; //THIS IS MY COUNTER FOR EXAMPLE!!!

    public MyIntentService() {
        super("MyIntentService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        progress = 0;
        int tiempo_disponible = intent.getIntExtra("minutos_disponible", 0);

        if (mBroadcaster == null){

            mBroadcaster = new BroadcastNotifier(this);
        }
        // Broadcasts an Intent indicating that processing has started.
        mBroadcaster.broadcastIntentWithState(Constants.STATE_ACTION_STARTED);

        mBroadcaster.broadcastIntentWithState(Constants.STATE_ACTION_RUNNING);

        while (progress < tiempo_disponible) {

            progress++;
            try {
                Log.i(Constants.TAG, "Procesing " + progress);
                mBroadcaster.notifyProgress(progress);
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        // Reports that the feed retrieval is complete.
        mBroadcaster.broadcastIntentWithState(Constants.STATE_ACTION_COMPLETE);
    }

    @Override
    public void onDestroy() {
        progress = 1000000; // WHITH THAT YOU FINISH THE CICLE IF tiempo_disponible NEVER IS MAYOR THAT 1000000, YOU CAN USE OTHER CONDITIONAL!!!!!!
        super.onDestroy();
    }
} 

通过这种方式,当您使用stopService方法停止服务时,您也将停止进程o计数器。

public void stopService(){
        context.stopService(intent);
        LocalBroadcastManager.getInstance(context).unregisterReceiver(responseReceiver);
        responseReceiver = null;
        intent = null;
}

小心! @yaircarreno

答案 4 :(得分:1)

如果您要跟踪GPS位置,则可能使用了GoogleApiClient

概念是服务不会停止,

如果GoogleApiClient实例仍在其中连接。

(或任何其他需要首先销毁/取消注册的问题)

为了使其有效,请在您的服务中实施onDestroy()

@Override
public void onDestroy()
{
    // Unregistered or disconnect what you need to
    // For example: mGoogleApiClient.disconnect();
    super.onDestroy();
}

答案 5 :(得分:0)

每次调用停止服务时,也许你正在创建一个新的Intent。

stopService(new Intent(GPSLoc.this, MyService.class));

也许试试:

Intent intnet = new Intent(GPSLoc.this, MyService.class); // create el service

startService(intenet); 
stopService(intent);

答案 6 :(得分:0)

对于那些想要定期向服务器发送请求的人来说,这是我的解决方案。你应该在你的活动或片段活动

中有这个
{
private static final Long UPDATE_LOCATION_TIME  = 30 * 60 * 1000l; // 30 minute

private AlarmManager alarm;
private PendingIntent pIntent; 
...

@Override
    protected void onResume() {
        super.onResume();

        // Run background service in order to update users location
        startUserLocationService();

        Log.e(TAG, "onResume");
    }

    @Override
    protected void onStop() {
        super.onStop();

        stopUserLocationService();

        Log.e(TAG, "onStop");
    }

private void startUserLocationService() {
        Log.i(TAG, "Starting service...");
        Intent intent = new Intent(MainFragmentHolder.this, ServiceUserLocation.class);
        pIntent = PendingIntent.getService(this, 0, intent, 0);

        alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
        Calendar cal = Calendar.getInstance();
        alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), UPDATE_LOCATION_TIME, pIntent);
    }

    private void stopUserLocationService() {
        alarm.cancel(pIntent);
        Intent intent = new Intent(MainFragmentHolder.this, ServiceUserLocation.class);
        stopService(intent);
    }

}

答案 7 :(得分:0)

通过将添加的视图移至WindowManager ondestroy

解决了我的问题
public void onDestroy() {
    isRunning = false;
    super.onDestroy();
    if (checkBox!=null) {
        windowManager.removeView(getlayoutparm(fabsetting,fabrateus,fabexit,true)); 
        windowManager.removeView(checkBox); 
    }
 }

答案 8 :(得分:0)

在我的情况下,几乎同时使用stopService调用startService,因此不会停止任何服务。尝试延迟stopService几秒钟。 :)

答案 9 :(得分:0)

@覆盖

public void onDestroy() {

    Log.d(TAG, "onDestroy");
    super.onDestroy();
    if (mLocationManager != null) {

        for (int i = 0; i < mLocationListeners.length; i++) {

            try {

                mLocationManager.removeUpdates(mLocationListeners[i]);

            } catch (Exception ex) {

                Log.d(TAG, "fail to remove location listners, ignore", ex);

            }

        }

    }

}

答案 10 :(得分:0)

我发现停止服务的最佳方法是自行停止。这样,您可以确定它实际上将停止并保留数据完整性。如果您想从外部(活动)进行操作,通常会使用全局静态属性。

如果我有MyServiceMyActivityMyObject,请按示例(Kotlin)

我的对象

object MyObject{
    abort = false
}

我的服务     

override fun onHandleIntent(intent: Intent?) {
    startForeground(id,notification)   
    for (i in range){
        if (MyObject.abort) break
        // RUN SOME CODE HERE
    }
    stopForeground(true)
    stopSelf()
}

MyActivity

fun startService() {
    startForegroundService(Intent(this, OptimizationService::class.java))
}
fun stopService() {
    MyObject.abort = true
}