意外的服务行为

时间:2016-02-25 09:42:17

标签: android service

我正在尝试创建一个Service,每24小时打开一次stackoverflow网站,我的代码如下所示:

public class StackServices extends Service {
private Handler mPeriodicEventHandler;
private static final String TAG = "Debug";
private static final long WAITING_TIME = 1000 * 60 * 60 * 24; //24 hours
public IBinder onBind(Intent intent) {
    return null;
}
@Override
public void onCreate() {
    super.onCreate();
    Log.d(TAG, "Service Created");
    mPeriodicEventHandler = new Handler();
}
@Override
public void onDestroy() {
    mPeriodicEventHandler.removeCallbacks(doPeriodicConnect);
    Log.d(TAG, "Service Destroyed");
    super.onDestroy();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.d(TAG, "Service started a command");
    mPeriodicEventHandler.post(doPeriodicConnect); //in order to load url when service starts
    return Service.START_STICKY;
}
private Runnable doPeriodicConnect = new Runnable() {
    public void run()
    {
        String url = "http://www.stackOverflow.com";
        loadURL(url);

        mPeriodicEventHandler.postDelayed(doPeriodicConnect, WAITING_TIME);
    }
};
private void loadURL(String url) {
    Calendar calendar = Calendar.getInstance();
    Log.d(TAG, String.format("Service loaded on: %s", calendar.getTime() ));
    Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
    intent.addFlags(intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);
}

}

我点击按钮启动ServiceActivity实施OnClickListener

@Override
public void onClick(View view) {
    int viewId = view.getId();

    switch (viewId){
        case R.id.btnStartStopService:
            if (isServiceRunning){
                this.stopService(new Intent(this, StackServices.class));
                Toast.makeText(MainActivity.this, R.string.service_shutdown, Toast.LENGTH_SHORT).show();
                btnStartStopService.setText(getString(R.string.btn_start_service));
                Log.d("Debug","service is running and you clicked shutdown"); //TODO delete me
            } else {
                Toast.makeText(getApplicationContext(), R.string.service_started, Toast.LENGTH_SHORT).show();
                this.startService(new Intent(this, StackServices.class));
                Log.d("Debug", "service is not running and you clicked start"); //TODO delete me
                finish();
            }
            break;
        default:
            Toast.makeText(MainActivity.this, R.string.dont_know_what_to_do, Toast.LENGTH_SHORT).show();
            break;
    }
}

到目前为止一直很好,但有些事情是错误的,当我使用按钮启动服务时,在24小时内我多次打开和关闭应用程序,我的服务正在重新创建并再次加载网站。我想知道为什么..?

这对我来说不合适。我写了一些Log.d()消息来看看会发生什么。

  • 调试:已创建活动
  • 调试:服务运行检查
  • 调试:服务未运行,您单击了开始
  • 调试:已创建服务
  • 调试:服务启动了一个命令
  • 调试:服务已加载:2月25日星期二10:08:11 GMT + 02:00 2016
  • 调试:活动销毁
  • 调试:已创建活动
  • 调试:服务运行检查
  • 调试:活动销毁
  • 调试:已创建活动
  • 调试:服务运行检查
  • 调试:活动销毁
  • 调试:已创建活动
  • 调试:服务运行检查
  • 调试:已创建服务
  • 调试:服务启动了一个命令
  • 调试:服务已加载:2月25日星期二10:08:53 GMT + 02:00 2016

1 个答案:

答案 0 :(得分:1)

您的服务从START_STICKY返回onStartCommand()

这意味着虽然系统可能会在某个时候销毁它,但它会被重新创建。一个重要细节:

  

如果没有任何挂起的启动命令要传递给服务,它将使用null intent对象调用,因此您必须注意检查这一点。

(来自documentation for START_STICKY

为避免频繁重新加载网页,您可以像这样更改onStartCommand()方法:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    if (intent != null)
    {        
        // only do this when started by activity
        mPeriodicEventHandler.post(doPeriodicConnect); 
    }
    return Service.START_STICKY;
}

但也许你也应该重新考虑一下你是否真的需要Service全天候运行。请查看AlarmManager,查看此guide