【问题标题】:how to prevent service to run again if already running android如果已经在运行android,如何防止服务再次运行
【发布时间】:2012-05-31 03:36:54
【问题描述】:

单击按钮时,我想使用方法startService(new Intent(currentActivity.this,MyService.class)) 启动服务,但如果服务正在运行,我不想调用此方法以避免运行已经在运行的服务。这是怎么可能的。我同时使用两者Intent 服务Service 在同一个项目中,并希望对两者应用相同的条件。

【问题讨论】:

标签: android service android-service


【解决方案1】:

因此,为了避免一次又一次地重新启动任务,您可以使用布尔值,即任务已经启动或正在进行。将方法放在 oncreate 和 onstartCommand 中,并用布尔值检查:

 boolean isTimerTaskRunning = false;
private boolean isServiceKeepRunning(){
        SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
        return settings.getBoolean("silentModeKeepRunning", true);
    }

@Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG, "onCreate: Called");
        Log.i(TAG, "onCreate: keepRunning "+isServiceKeepRunning());
        if(!isTimerTaskRunning) {
            startTimerTask();
            isTimerTaskRunning = true;
        }
        //startForeground(REQUEST_CODE /* ID of notification */, notificationbuilder().build());

    }

 @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        localData = new LocalData(this);
      //  return super.onStartCommand(intent, flags, startId);
        Log.i(TAG, "onStartCommand: Called");
        Log.i(TAG, "onStartCommand: keepRunning "+isServiceKeepRunning());

        Toast.makeText(this, "This is The Mode For Silent. ", Toast.LENGTH_LONG).show();

        if(!isTimerTaskRunning) {
            Log.i(TAG, "TimerTask was not Running - started from onStartCommand");
           startTimerTask();
           isTimerTaskRunning = true;

        }else {
            Log.i(TAG, "TimerTask was already Running - checked from onStartCommand");

        }
        //return START_REDELIVER_INTENT;
        startForeground(REQUEST_CODE /* ID of notification */, notificationbuilder().build());

        return  START_STICKY;
}

【讨论】:

    【解决方案2】:

    每当我们从任何 Activity 启动任何服务时,Android 系统都会调用该服务的 onStartCommand() 方法,如果该服务尚未运行,则系统会先调用 onCreate(),然后再调用 onStartCommand()。

    意思是说 android 服务在其生命周期中只启动一次并保持运行直到停止。如果任何其他客户端想要再次启动它,那么只有 onStartCommand() 方法会一直调用。

    【讨论】:

    • 有文档来源吗?
    【解决方案3】:

    使用startService()。 启动服务将调用onStartCommand() 如果服务尚未启动,它将调用onCreate()。初始化您的变量和/或在onCreate() 中启动一个线程。

    【讨论】:

    • 这是正确的答案。 onCreate() 被忽略了。
    • 这意味着我们要启动多少次服务 onCreate 只调用一次?
    【解决方案4】:

    绑定你的服务;开始通话时:

    Intent bindIntent = new Intent(this,ServiceTask.class);
        startService(bindIntent);
        bindService(bindIntent,mConnection,0);
    

    然后要检查您的服务是否正常工作,请使用如下方法:

        public static boolean isServiceRunning(String serviceClassName){ 
                 final ActivityManager activityManager = (ActivityManager)Application.getContext().getSystemService(Context.ACTIVITY_SERVICE);     
                 final List<RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);      
               for (RunningServiceInfo runningServiceInfo : services) {         
                 if (runningServiceInfo.service.getClassName().equals(serviceClassName)){             
                    return true;         
                 }     
               }     
             return false; 
            }
    

    【讨论】:

    • 仅当我将服务绑定到活动时,此代码是否有效?我认为将服务绑定到活动将一直运行,直到应用程序运行。请评论
    • 这并不总是有效。它没有考虑“服务被停止”。它主要用于显示正在运行的服务 UI。我用过这个,但它在 KitKat 中总是不起作用。相反,您可以始终使用 startService 并使用 service onCreate 和 onStartCommand 来完成您的任务。这是正确的方法。
    • 为什么这里需要绑定服务?我们不能只使用Started Service吗?
    • getRunningServices 已弃用
    【解决方案5】:

    一个服务只会运行一次,所以你可以多次调用startService(Intent)

    您将在服务中收到onStartCommand()。所以请记住这一点。

    来源: 请注意,对Context.startService() 的多次调用不会嵌套(尽管它们确实会导致对onStartCommand() 的多次相应调用),因此无论启动多少次,一旦调用Context.stopService()stopSelf() 就会停止服务;然而,服务可以使用他们的stopSelf(int) 方法来确保服务在启动的意图被处理之前不会停止。

    在:http://developer.android.com/reference/android/app/Service.html 主题:服务生命周期

    【讨论】:

    • 感谢您的快速回复。您的评论将对我有很大帮助,但如果服务正在运行,则不想再次调用这些方法。还有其他想法吗???
    • @AtulBhardwaj:调用startService()总是触发onStartComand()。时期。所以,要么不要调用startService(),要么有一个更聪明的onStartCommand() 可以处理被多次调用。
    最近更新 更多