【问题标题】:Android - Calling a system service in fixed intervals from another serviceAndroid - 从另一个服务以固定间隔调用系统服务
【发布时间】:2011-08-06 15:11:00
【问题描述】:

正如问题所暗示的,我想知道如何编写一个线程来调用系统服务,然后等待一段时间,然后再调用从注册的BroadcastReceiver 回调到onReceive 的所述系统服务函数.

换句话说,我正在尝试在我的自定义服务中调用 Wifi 扫描服务(使用IntentFilters 注册BroadcastReceiver),以便获取当前可用的 SSID。我知道我最终会对收到的数据做什么,这与这个问题无关。但是,在onReceive 内再次调用startScan 之前,我需要等待一段时间,这就是我试图确定最佳行动方案的地方。

我设法在我的线程中以这种方式调用 wifi 扫描仪:

    private Object _lock = new Object();

    private final long SLEEP_TIME = 15000; //Scan every 15 secs
    private final long WIFI_SCAN_TIMEOUT = 60000; //One minute timeout for getting called back, otherwise, initiate a new scan.

   @Override
    public void run() {
        while(running){
            //Start a new scan;
            wifiSearchComplete = false;
            _wifiMan.startScan();
            while(!wifiSearchComplete){
                synchronized(_lock){
                    try{
                        _lock.wait(WIFI_SCAN_TIMEOUT);
                    } catch (InterruptedException ie){
                         Log.d(TAG, TAG+".run() caught " + ie.getMessage() +" when trying to sleep for " + (WIFI_SCAN_TIMEOUT/1000) +"secs.");
                         Thread.currentThread().interrupt();
                    }
                }
                if(!wifiSearchComplete){
                    synchronized(_lock){
                        //Try scanning again since we didn't get called back at all;
                        _lock.notify();
                    }
                }
            }
        }
    }

    public boolean isRunning(){
        return running;
    }

    public void stop(){
        synchronized(_lock){
            running = false;
            //unregister receivers and cleanup
            _lock.notify();
        }
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        synchronized(_lock){
               wifiSearchComplete = true;
               //iterate through our SSID's
                try{
                    _lock.wait(SLEEP_TIME);
                } catch (InterruptedException ie){
                     Log.d(TAG, TAG+".onReceive() caught " + ie.getMessage() +" when trying to sleep for " + (SLEEP_TIME/1000) +"secs.");
                     Thread.currentThread().interrupt();
                }
                _lock.notify();
            }
    }

但是,即使它在再次扫描之前每 15 秒等待一次,但在尝试退出我的测试活动(调用 onDestroy)时,它会在取消绑定服务之前阻塞主线程以等待睡眠时间。换句话说,这是尝试在不阻塞的情况下完成我想做的事情的适当方式,还是我必须简单地创建一个BroadcastReceiver 并在onReceive 的末尾调用Thread.sleep,然后再调用开始新的扫描?

【问题讨论】:

    标签: android multithreading service broadcastreceiver android-context


    【解决方案1】:

    您应该实现一个 IntentService。在您的实现中覆盖 onHandleIntent() 以进行 WiFi 扫描。

    接下来,使用 AlarmManager 安排在某个时间间隔向您的 IntentService 发送 Intent。组成你自己的动作名称:“diago.intent.scan_wifi”或类似的东西。如果您使用“不精确的重复间隔”之一(例如 15 分钟),那么 Android 操作系统将同时安排所有其他服务,以尽量减少手机必须从睡眠模式唤醒的次数。

    最后,实现一个 BroadcastReceiver 来响应 ACTION_BOOT_COMPLETED 并调用你的代码来调度 AlarmManager。这将在启动时启动您的服务。

    这样当AlarmManager发送意图时,你的服务会被加载,执行扫描然后退出。

    【讨论】:

    • 我只希望我的服务在应用程序的活动绑定到它时运行,这意味着我的家庭活动将是最后一个解除绑定的活动,从而关闭服务。您指定的时间间隔太长,我们的想法是将该数据发送回有界活动并在短波中检查更多 SSID,而不是通过通知栏。
    猜你喜欢
    • 1970-01-01
    • 2017-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-31
    • 2015-11-10
    • 1970-01-01
    • 2013-06-15
    相关资源
    最近更新 更多