Dianne- I expect your suggestion is sound, since you do know Android so well, and in particular, what Handlers are good for and how to use them. I also expect that the reason Diego did not use a Handler was that he could easily find copious documentation on how to use a "raw thread", but nothing comparable on how to use a Handler; he almost got the synchronization idiom right: the !wifiSearchComplete test needs to be repeated inside the synchronized block or moved inside entirely (http://download.oracle.com/javase/tutorial/essential/concurrency/ guardmeth.html).
Since he almost got it right, he seems to have tolerably good grasp of Java objects and methods Thread, locks, wait(), notify() and the synchronized keyword. But to implement the HandlerThread technique, he has to learn several new objects: Handler, HandlerThread, Message, Looper, MessageQueue. The http://developer.android.com/reference/android/os/Handler.html link certainly leaves much to be desired. Badly written sentences like "When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue." leave the reader doubting it is worth the bother, especially if the reader has no good sample code in front of him. What is so wrong with that sentence? 1) pronoun reference for 'it' is way too vague: does 'it' stand for 'Handler' or for thread, or the message queue? After some reflection it appears that 'Handler' has to be the right answer, but then 2) what get executed "as they come ouf of the message queue"? It would appear to mean that both messages and runnables get executed, but what it means to execute a message is far from clear. It is a type mismatch: one executes runnables but handles messages. Not to mention, 3) it says, "to be executed in the future", but it is far from clear which method does this execution. Also, the purpose of Handlers is described as being mainly either one of two things: either 1) scheduling for the future, or 2) executing on a different thread. Which is Diego doing? Apparently not 2), since you said "if the code is not doing blocking". But 1) isn't quite right either, since he wants to execute the scan again after WIFI_SCAN_TIMEOUT only if the previously initiated scan does NOT complete. Of course, he could schedule and unschedule as needed, but this looks like it could turn out to be more complicated than debugging the 'raw thread' code. Of course, I can't guarantee that the one change I suggest will fix his problem, since I have not run it; I have not run it, because I am not seeing code for the Service. Even more "of course", it is quite possible that a pointer to sample code that does the kind of timing he needs, without excess baggage, showing how to use handleMessage() and hasMessages() to do timing by responding to the delayed message (and where to place them to avoid ANR -- his timeouts are 15S and 60S), could tip the balance in favor of using Handler. On Apr 18, 4:22 pm, Dianne Hackborn <[email protected]> wrote: > I suggest not using a raw thread. If you need it on a separate thread, use > a HandlerThread and Handler.sendMessageDelayed() to do your timing. > > Even better -- if the code is not doing blocking operations, there is no > need for another thread at all; just make a class with a Handler in it and > use Handler.sendMessageDelayed() to schedule your work on the main thread. > > On Mon, Apr 18, 2011 at 3:58 PM, Diego Tori > <[email protected]>wrote: > > > So yeah, I managed to try calling the wifi scanner in this fashion within > > my thread: > > 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(); > > } > > } > > > However, even though it waits every 15 seconds before it scans again, when > > trying to exit my test activity (calling onDestroy) it blocks the main > > thread for the sleep time, before it unbinds the service. In other words, is > > this the appropriate way of trying to accomplish what I want to do w/o > > blocking, or do I have to simply create a BroadcastReceiver and call > > Thread.sleep at the end of onReceive before calling starting a new scan? > > > -- > > You received this message because you are subscribed to the Google > > Groups "Android Developers" group. > > To post to this group, send email to [email protected] > > To unsubscribe from this group, send email to > > [email protected] > > For more options, visit this group at > >http://groups.google.com/group/android-developers?hl=en > > -- > Dianne Hackborn > Android framework engineer > [email protected] > > Note: please don't send private questions to me, as I don't have time to > provide private support, and so won't reply to such e-mails. All such > questions should be posted on public forums, where I and others can see and > answer them. -- You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/android-developers?hl=en

