【问题标题】:Stop background Service When application goes to background当应用程序进入后台时停止后台服务
【发布时间】:2014-12-13 20:31:31
【问题描述】:

我的 android 应用程序中有后台服务,我从 MainActivity onResume() 方法启动服务并且它工作正常。但是当用户按下主页按钮时我如何停止服务。因为当前当用户按下主页按钮时应用程序移动到背景,然后用户打开其他应用程序,然后在一段时间后调用我的服务方法并强制停止应用程序。下面是我的启动服务代码 -

Intent msgIntent = new Intent(mContext, MyBackgroundService.class);
        startService(msgIntent);

提前致谢。

已编辑

在我的服务中,我使用以下代码 -

 public void callAsynchronousTask() {
final Handler handler = new Handler();
timer = new Timer();
TimerTask doAsynchronousTask = new TimerTask() {       
    @Override
    public void run() {
        handler.post(new Runnable() {
            public void run() {       
                try {
                    callWebservice();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
};
timer.schedule(doAsynchronousTask, START_DELAY, DELAY);
 }

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    callAsynchronousTask();
    return Service.START_NOT_STICKY;
}

@Override
public void onCreate() {
    mContext = this;
    super.onCreate();
}

@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onDestroy() {
    super.onDestroy();
    if(timer!=null){
        timer.cancel();
    }
    stopSelf();
}

在我的活动中,我使用以下代码停止服务 -

@Override
protected void onStop() {
    try{
         stopService(new Intent(this, MyBackgroundService.class));
         isServiceRunning = false;
    }
   catch(Exception e){
    e.printStackTrace();
   }
    super.onStop();
}

@Override
protected void onPause() {
    try{
         stopService(new Intent(this, MyBackgroundService.class));
         isServiceRunning = false;
    }
    catch(Exception e){
        e.printStackTrace();
    }
    super.onPause();
}

但我的服务在我使用其他应用程序时运行,它强制停止应用程序。我从后台服务调用一些 web 服务,然后将服务响应存储在数据库中。

【问题讨论】:

    标签: android background-service


    【解决方案1】:

    在 onPause() 和 onStop() 中停止服务

    mContext.stopService(new Intent(mContext,
                         MyBackgroundService.class))
    

    【讨论】:

      【解决方案2】:
      @Override
          public boolean onKeyDown(int keyCode, KeyEvent event) {
              if(keyCode==KeyEvent.KEYCODE_HOME){
                  Log.e("home key pressed", "****");   
                  // write your code here to stop the activity
                  enter code here
              }
              return super.onKeyDown(keyCode, event);
          }
      
          @Override
          protected void onPause() {
              Log.e("home key pressed on pause", "****");
              // write your code here to stop your service 
              super.onPause();      
          }
      

      上面的代码会一直检查用户是否按下了home键。

      【讨论】:

      • 我已经尝试过你的代码,但是当按下主页按钮时,不会调用 onKeyDown 方法。
      • 您必须从后台服务更新 ui,这可能会导致崩溃。如果是这样,您需要对活动的上下文进行检查,并在 onPause 和 Onkey down 方法上使其为空,然后在更新 ui 之前对其进行检查。
      【解决方案3】:

      当我们打开其他应用程序时,我们的应用程序(在后台)会从内存中清除但是整个应用程序不会被删除,但一些不需要的数据和活动会完成。 在您的情况下,当尝试更新 UI 时,要更新的活动会从内存和正在运行的后台服务中清除,然后它会因抛出 NullPointerException 而崩溃。

      因此,请在 onCreate() 中保存 activty(要更新其 UI)的引用,并在 finish() 方法中将引用设置为 null,然后在后台服务中检查此引用,如果它不为 null,然后更新UI 否则不更新。

      // Global Class for saving the reference
      class GlobalReference{
            public static <name_of_your_activity> activityRef;
      }
      

      在你的活动中

       onCreate(){
           GlobalReference.activityRef = this;
       }
      
      
      finish(){
          GlobalReference.activityRef = null;
      }
      

      在您的后台服务中

      if( GlobalReference.activityRef != null){
          // update the UI of your activity
      }
      

      希望此代码能解决您的问题。 快乐编码...

      【讨论】:

        【解决方案4】:

        按下 Home 按钮会导致 OnPause() 函数。覆盖 onPause() 并调用 stopService: mContext.stopService(新意图(mContext, MyBackgroundService.class))

        【讨论】:

        • 请检查更新的问题。因为我已经尝试了您的代码,但是当应用程序在后台并且其他一些应用程序正在运行时,应用程序仍然崩溃。