2013-02-24 25 views
1

我有一個在特定時間觸發的BroadcastReceiver(通過AlarmManager)。它以編程方式安排,取決於用戶設置的偏好。postRelayed在BroadcastReceiver

的廣播接收器做(簡體和僞代碼):

public void onReceive(Context context, Intent intent) { 
    handler = new Handler(); 
    wifiManager.setWifiEnabled(true); 
    // Wait a few seconds to activate wifi and get IP 
    handler.postDelayed(new Runnable() { 
    void run() { 
     doTheJob(); 
    } 
    }, 30000); 
} 

public void doTheJob() { 
    doSomethingAndTheOther(); // this starts service: context.startService(i); 
    wifiManager.setWifiEnabled(false); 
} 

我已經用了好幾年的HTC Desire這段代碼沒有問題。此外,沒有用戶抱怨它無法正常工作。

不過,我最近買了一臺Galaxy S3,並沒有像預期的那樣工作。當我在未來幾分鐘內設置鬧鐘(使用告訴的首選項)時,它會按預期工作:BroadcastReceiver喚醒,wifi打開,等待等待,工作完成並關閉WiFi。

但是,如果我在夜間設置鬧鐘(例如,3:00:00),則不會觸發鬧鐘,打開wifi ......並且沒有其他任何事情。這項工作既沒有完成,也沒有顯示最終沒有關閉wifi。我創建了日誌並調用了postDelayed(),但Runnable.run()永遠不會被調用。

看起來,我的BroadcastReceiver進程在run()被調用之前即將死亡。

任何想法爲什麼?任何關於如何避免它的想法?

+0

你在onReceive()中創建處理程序嗎? – sandrstar 2013-02-24 08:51:27

+0

@sandrstar:是的,我喜歡。我編輯了僞碼來記錄這一點。 – 2013-02-24 16:24:50

回答

5

BroadcastReceivers在使用後會立即銷燬。我不確定它是否會在之前的某個版本的Android中發生變化,但是您絕對不應該認爲廣播接收器的實例會留在其中。他們的目的是立即處理事件,像使用AlarmManager或在服務中那樣延遲處理。

+0

呃...好點... doSomethingAndTheOther()開始一項服務來完成這項艱鉅的工作(添加了一個註釋來記錄它)。但是,您是否建議在服務內部完成postDelayed()?這意味着嚴重的重構,但是有道理。 – 2013-02-24 16:27:40

+0

是的。 postDelayed將在Handler的消息隊列中放置一個事件。處理程序由Receiver所有,並且沒有其他引用。所以當它的單個所有者被摧毀時它將被銷燬,並且當時它的信息將消失。 – 2013-02-24 16:35:12

+0

這種方法的第一次測試是成功的。經過一些測試後,我會檢查它是否被接受。 – 2013-02-25 06:28:24