2013-10-29 47 views
0

我正在開發一個Android應用程序,它啓動後臺任務以每x秒從用戶訪問一次URL(用戶定義的時間間隔,默認爲60)。我的結構是這樣:AlarmManager.setRepeating - 服務似乎沒有重複

MainActivity

這個時間表通過AlarmManager報警:

public static void scheduleAlarm(Context voContext, int viCheckInterval) 
{ 
    try { 
     moAlarmManager = (AlarmManager) voContext.getSystemService(Context.ALARM_SERVICE); 
     Intent intent = new Intent(voContext, AlarmReceiver.class); 
     moAlarmIntent = PendingIntent.getBroadcast(voContext, 0, intent, 
                PendingIntent.FLAG_CANCEL_CURRENT); 
     Calendar time = Calendar.getInstance(); 
     time.setTimeInMillis(System.currentTimeMillis()); 
     time.add(Calendar.SECOND, viCheckInterval); 
     moAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(), 
             time.getTimeInMillis(), moAlarmIntent); 
    } catch (Exception e) { 
     Log.e("MessageCheckAlarmHandler", e.toString()); 
    } 
} 

AlarmReceiver

這是啓動服務的BroadcastReceiver:

@Override 
public void onReceive(Context context, Intent intent) 
{ 
    Context oAppContext = context.getApplicationContext(); 

    if (oAppContext == null) { 
     oAppContext = context; 
    } 

    Intent serviceIntent = new Intent(oAppContext, MessagingService.class); 
    oAppContext.startService(serviceIntent); 
} 

的MessagingService

這就造成我們內部的記錄(記錄在TCP)並啓動的AsyncTask稱爲FetchPageTask:

public class MessagingService extends Service 
{ 
    @Override 
    public void onCreate() 
    { 
     super.onCreate(); 

     ... 

     this.acquireLocks(); 

     try { 
      String sCheckerUrl = oPreferences.getString("pref_server", ""); 
      int sCheckerPort = Integer.parseInt(oPreferences.getString("pref_server_port", 
                      "8050")); 
      sCheckerUrl = String.format(URL, sCheckerUrl, sCheckerPort); 

      this.moFetchInboxTask = new FetchPageTask(this.logger, this); 
      this.moFetchInboxTask.execute(sCheckerUrl); 
     } finally { 
      this.releaseLocks(); 
      this.stopSelf(); 
     } 
    } 

    @Override 
    public void onDestroy() 
    { 
     super.onDestroy(); 

     this.logger.close(); 
    } 

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

    /** 
    * Acquire a WakeLock and a WifiLock. 
    */ 
    private void acquireLocks() 
    { 
     try { 
      // Acquire a wake lock to prevent the device from entering "deep sleep" 
      PowerManager oPowerManager = (PowerManager) this.getSystemService(Context.POWER_SERVICE); 
      this.moWakeLock = oPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); 
      this.moWakeLock.acquire(); 
      // Acquire a WiFi lock to ensure WiFi is enabled 
      WifiManager wm = (WifiManager) this.getSystemService(Context.WIFI_SERVICE); 
      this.moWifiLock = wm.createWifiLock(WifiManager.WIFI_MODE_FULL, TAG); 
      this.moWifiLock.acquire(); 
     } catch (Exception e) { 
      this.logger.error(TAG + "->onCreate()", "Error acquiring locks: " + e.toString()); 
     } 
    } 

    /** 
    * Release our WakeLock and WifiLock. 
    */ 
    private void releaseLocks() 
    { 
     try { 
      this.moWakeLock.release(); 
      this.moWifiLock.release(); 
     } catch (Exception e) { 
      this.logger.error(TAG + "->releaseLocks()", e.toString()); 
     } 
    } 
} 

FetchPageTask

這延長的AsyncTask,並做了所有獲取頁面和解析XML的工作。它還會添加通知,並根據需要對數據進行操作。


這一切工作正常,但不會隨後運行。我知道AsyncTask的工作方式與以前使用純Java通過ScheduledExecutorService和ScheduledFuture一樣工作,並且工作正常。我決定改用AlarmManager的唯一原因是出於可維護性的目的。

回答

2

首先,您正在設置您的鬧鐘以便立即發生,然後每隔約43年發生一次。這不太可能是你想要的。修改您的通話的第三個參數setRepeating()要以毫秒爲單位,現在正好是午夜以來的1月1日1970年

第二盤的毫秒數所需週期,您採集的WakeLock爲時已晚。不能保證您的acquireLocks()將有機會在設備入睡之前運行。 My WakefulIntentServicethe new WakefulBroadcastReceiver提供更好的模式將控制權傳遞給IntentService

+0

啊,現在這可能是一個肯定的問題。謝謝你指出這一點。關於喚醒者,我也會研究它們。非常感謝鏈接! – euantorano

0

我認爲你不需要這裏的日曆。你只是想每隔x秒運行一次,所以它會是這樣的:

moAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 
            viCheckInterval, moAlarmIntent); 

// viCheckInterval should be long miliseconds