2016-02-25 48 views
0

我想創建一個Service打開,每24小時一個計算器的網站和我的代碼如下所示:意外的服務行爲

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); 
} 

}

我通過點擊按鈕啓動Service和我Activity工具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; 
    } 
} 

到目前爲止好,但什麼是錯的,當我ST使用按鈕進行服務,並在24小時內打開和關閉應用程序數次,我的服務正在重新創建並再次加載站點。我想知道爲什麼..?

這對我來說不合適。我寫了一些Log.d()消息來看看會發生什麼。

  • 調試:活動創造
  • 調試服務的運行檢查
  • 調試:服務沒有運行,並且單擊開始
  • 調試:服務創建
  • 調試:服務啓動命令
  • 調試:服務加載時間:星期四2月25日10:08:11 GMT + 02:00 2016
  • 調試:活動被破壞
  • 調試:活動創造
  • 調試服務的運行檢查
  • 調試:活動破壞
  • 調試:活動創造
  • 調試服務的運行檢查
  • 調試:活動破壞
  • 調試:活動創造
  • 調試:服務運行檢查
  • 調試:創建服務
  • 調試:服務啓動命令
  • 調試:服務裝上:週四2月25日10時08分53秒GMT + 02:00 2016

回答

1

你的服務返回從onStartCommand()START_STICKY

這意味着雖然它可能會在某個時候被系統破壞,但它會被重新創建。一個重要的細節:

如果沒有任何掛起的啓動命令要傳遞給服務,它將被調用一個空的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 24/7全天候運行。看看AlarmManager,看到這guide

+0

但在日誌我沒有看到「服務銷燬」,我有Log.d(標記,「服務銷燬」); onDestroy方法。我已經閱讀了'AlarmManager',但API是19我想在較低的API中運行服務。 – MeLine

+1

@MeLine - onDestroy()不保證被調用。但是你看到服務已經創建。因爲它是一種Singleton,這意味着它以前被銷燬 – 0X0nosugar

+0

@MELine - AlarmManager在API級別1之後,只有在級別19時行爲發生了變化,請參閱[documentation](http://developer.android.com /reference/android/app/AlarmManager.html) – 0X0nosugar