You are on page 1of 40

CHAPTER 1-

http://commonsware.com/AdvAndroid

; vance

"ervice Patterns

0n The Busy Coder's Guide to Android Deve opment , Ae 'o!ere" hoA to 'reate an" 'onsume ser!i'es an" 'o!ere" some basi' ser!i'e patterns. +oAe!er, ser!i'es 'an 'ertainly "o more than Ahat is 'o!ere" in those intro"u'tory patterns. 0n this 'hapter, Ae Aill e>amine some more poAer&ul options &or ser!i'es, in'lu"ing remote ser!i'es an" using ser!i'es in the role o& G'ron NobsG or Gs'he"ule" tasksG.

Cemote "ervices
1y "e&ault, ser!i'es are use" Aithin the appli'ation that publishes them. +oAe!er, it is possible to e>pose ser!i'es &or other appli'ations to take a"!antage o&. 8hese are basi'ally inter-pro'ess e"itions o& the bin"ing pattern an" 'omman" patterns outline" in The Busy Coder's Guide to Android Deve opment. We start Aith an e>planation o& the inter-pro'ess 'ommuni'ation (0#C) me'hanism o&&ere" in An"roi" &or alloAing ser!i'es to Aork Aith 'lients in other appli'ations. 8hen, Ae mo!e onto the steps to alloA a 'lient to 'onne't to a remote ser!i'e, be&ore "es'ribing hoA to turn an or"inary ser!i'e into a remote one. We then look at hoA one 'an implement a 'allba'k system to alloA ser!i'es, through 0#C, to pass in&ormation ba'k to 'lients. A&ter noting the possibility o& bin"er errors, Ae Arap by e>amining other Aays to get results &rom remote ser!i'es, ba'k to 'lients, Aithout going through bin"ing.
'30
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

'hen $PC Attac?sA


%er!i'es Aill ten" to o&&er 0#C as a means o& intera'ting Aith a'ti!ities or other An"roi" 'omponents. @a'h ser!i'e "e'lares Ahat metho"s it is making a!ailable o!er 0#CP those metho"s are then a!ailable &or other 'omponents to 'all, Aith An"roi" han"ling all the messy "etails in!ol!e" Aith making metho" 'alls a'ross 'omponent or pro'ess boun"aries. 8he guts o& this, &rom the stan"point o& the "e!eloper, is e>presse" in A0DL, the An"roi" 0nter&a'e Des'ription Language. 0& you ha!e use" 0#C me'hanisms like CFM, CF 1A, or the like, you Aill re'ogniCe the notion o& 0DL. A0DL "es'ribes the publi' 0#C inter&a'e, an" An"roi" supplies tools to buil" the 'lient an" ser!er si"e o& that inter&a'e. With that in min", let:s take a look at A0DL an" 0#C.

Write the AI$/


0DLs are &re?uently Aritten in a Glanguage-neutralG synta>. A0DL, on the other han", looks a lot like a -a!a inter&a'e. *or e>ample, here is some A0DL,
package com.commonsware.android.advservice5 "" >eclare t0e interface. interface IScript ; void e(ecuteScript String script!5 A

As Aith a -a!a inter&a'e, you "e'lare a pa'kage at the top. As Aith a -a!a inter&a'e, the metho"s are Arappe" in an inter&a'e "e'laration ( interface IScript ; ... A). An", as Aith a -a!a inter&a'e, you list the metho"s you are making a!ailable. 8he "i&&eren'es, though, are 'riti'al. *irst, not e!ery -a!a type 'an be use" as a parameter. Bour 'hoi'es are,

'3&
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

#rimiti!e !alues (int, float, double, boolean, et'.)


String an" C0arSeBuence -ist an" 8ap

(&rom java.util)

Any other A0DL-"e&ine" inter&a'es Any -a!a 'lasses that implement the <arcelable inter&a'e, Ahi'h is An"roi":s &la!or o& serialiCation

0n the 'ase o& the latter tAo 'ategories, you nee" to in'lu"e import statements re&eren'ing the names o& the 'lasses or inter&a'es that you are using (e.g., import com.commonsware.android.ISomet0ing). 8his is true e!en i& these 'lasses are in your oAn pa'kage O you ha!e to import them anyAay. 2e>t, parameters 'an be 'lassi&ie" as in, out, or inout. .alues that are out or 'an be 'hange" by the ser!i'e an" those 'hanges Aill be propagate" ba'k to the 'lient. #rimiti!es (e.g., int) 'an only be inP Ae in'lu"e" in &or the A0DL &or enable ! Nust &or illustration purposes.
inout

Also, you 'annot throA any e>'eptions. Bou Aill nee" to 'at'h all e>'eptions in your 'o"e, "eal Aith them, an" return &ailure in"i'ations some other Aay (e.g., error 'o"e return !alues). 2ame your A0DL &iles Aith the .aidl e>tension an" pla'e them in the proper "ire'tory base" on the pa'kage name. When you buil" your proNe't, either !ia an 0D@ or !ia Ant, the aidl utility &rom the An"roi" %DK Aill translate your A0DL into a ser!er stub an" a 'lient pro>y.

I ple ent the Interface


;i!en the A0DL-'reate" ser!er stub, noA you nee" to implement the ser!i'e, either "ire'tly in the stub, or by routing the stub implementation to other metho"s you ha!e alrea"y Aritten.

'31
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

8he me'hani's o& this are &airly straight&orAar",

Create a pri!ate instan'e o& the A0DL-generate" .Stub 'lass (e.g.,


IScript.Stub)

0mplement metho"s mat'hing up Aith ea'h o& the metho"s you pla'e" in the A0DL eturn this pri!ate instan'e &rom your on7ind ! metho" in the Service sub'lass

2ote that A0DL 0#C 'alls are syn'hronous, an" so the 'aller is blo'ke" until the 0#C metho" returns. +en'e, your ser!i'es nee" to be ?ui'k about their Aork. We Aill see e>amples o& ser!i'e stubs later in this 'hapter.

A Consumer Economy
F& 'ourse, Ae nee" to ha!e a 'lient &or A0DL-"e&ine" ser!i'es, lest these ser!i'es &eel lonely.

)ound for Success


8o use an A0DL-"e&ine" ser!i'e, you &irst nee" to 'reate an instan'e o& your oAn ServiceConnection 'lass. ServiceConnection, as the name suggests, represents your 'onne'tion to the ser!i'e &or the purposes o& making 0#C 'alls. Bour ServiceConnection sub'lass nee"s to implement tAo metho"s, 1.
onServiceConnected !,

Ahi'h is 'alle" on'e your a'ti!ity is boun" to

the ser!i'e 2. onService>isconnected !, Ahi'h is 'alle" i& your 'onne'tion en"s normally, su'h as you unbin"ing your a'ti!ity &rom the ser!i'e

'33
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

@a'h o& those metho"s re'ei!es a Component9ame, Ahi'h simply i"enti&ies the ser!i'e you 'onne'te" to. More importantly, onServiceConnected ! re'ei!es an I7inder instan'e, Ahi'h is your gateAay to the 0#C inter&a'e. Bou Aill Aant to 'on!ert the I7inder into an instan'e o& your A0DL inter&a'e 'lass, so you 'an use 0#C as i& you Aere 'alling regular metho"s on a regular -a!a 'lass (IScript.Stub.asInterface binder!). 8o a'tually hook your a'ti!ity to the ser!i'e, 'all bindService ! on the a'ti!ity,
bindService new Intent )com.commonsware.android.advservice.IScript)!@ svcConn@ Conte%t.7I9>16E?41C=:6?:!5

8he bindService ! metho" takes three parameters, 1. An Intent representing the ser!i'e you Aish to in!oke

2. Bour ServiceConnection instan'e /. A set o& &lags O most times, you Aill Aant to pass in 7I9>16E?41C=:6?:, Ahi'h Aill start up the ser!i'e i& it is not alrea"y running A&ter your bindService ! 'all, your onServiceConnected ! 'allba'k in the ServiceConnection Aill e!entually be in!oke", at Ahi'h time your 'onne'tion is rea"y &or use.

Re0uest for Service


Fn'e your ser!i'e inter&a'e obNe't is rea"y (IScript.Stub.asInterface binder!), you 'an start 'alling metho"s on it as you nee" to. 0n &a't, i& you "isable" some Ai"gets aAaiting the 'onne'tion, noA is a &ine time to re-enable them. +oAe!er, you Aill Aant to trap tAo e>'eptions. Fne is >ead4bject:%ception O i& this is raise", your ser!i'e 'onne'tion terminate" une>pe'te"ly. 0n this 'ase, you shoul" unAin" your use o& the ser!i'e, perhaps by 'alling onService>isconnected ! manually, as shoAn abo!e. 8he other is =emote:%ception, Ahi'h is a more general-purpose e>'eption in"i'ating a
'35
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

'ross-pro'ess 'ommuni'ations problem. Again, you shoul" probably 'ease your use o& the ser!i'e.

#etting Unbound
When you are "one Aith the 0#C inter&a'e, 'all unbindService !, passing in the ServiceConnection. @!entually, your 'onne'tion:s onService>isconnected ! 'allba'k Aill be in!oke", at Ahi'h point you shoul" null out your inter&a'e obNe't, "isable rele!ant Ai"gets, or otherAise &lag yoursel& as no longer being able to use the ser!i'e. Bou 'an alAays re'onne't to the ser!i'e, !ia bindService !, i& you nee" to use it again.

"ervice 5rom A*ar


@!erything &rom the pre'e"ing tAo se'tions 'oul" be use" by lo'al ser!i'es. 0n &a't, that prose originally appeare" in The Busy Coder's Guide to Android Deve opment spe'i&i'ally in the 'onte>t o& lo'al ser!i'es. +oAe!er, A0DL a""s a &air bit o& o!erhea", Ahi'h is not ne'essary Aith lo'al ser!i'es. A&ter all, A0DL is "esigne" to marshal its parameters an" transport them a'ross pro'ess boun"aries, Ahi'h is Ahy there are so many ?uirky rules about Ahat you 'an an" 'annot pass as parameters to your A0DL-"e&ine" A#0s. %o, gi!en our A0DL "es'ription, let us e>amine some implementations, spe'i&i'ally &or remote ser!i'es. Fur sample appli'ations O shoAn in the 6dvServices"=emoteService an" 6dvServices"=emoteClient sample proNe'ts O 'on!ert our 1eanshell "emo &rom The Busy Coder's Guide to Android Deve opment into a remote ser!i'e. 0& you a'tually Aante" to use s'ripting in an An"roi" appli'ation, Aith s'ripts loa"e" o&& o& the 0nternet, isolating their e>e'ution into a ser!i'e might not be a ba" i"ea. 0n the ser!i'e, those s'ripts are san"bo>e", only able to a''ess &iles an" A#0s a!ailable to that ser!i'e. 8he s'ripts 'annot a''ess your oAn appli'ation:s "atabases, &or e>ample. 0& the s'ript-e>e'uting

'36
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

ser!i'e is kept tightly 'ontrolle", it minimiCes the mis'hie& a rogue s'ript 'oul" possibly "o.

Service 1a es
8o bin" to a ser!i'e:s A0DL-"e&ine" A#0, you nee" to 'ra&t an 0ntent that 'an i"enti&y the ser!i'e in ?uestion. 0n the 'ase o& a lo'al ser!i'e, that 0ntent 'an use the lo'al approa'h o& "ire'tly re&eren'ing the ser!i'e 'lass. Fb!iously, that is not possible in a remote ser!i'e 'ase, Ahere the ser!i'e 'lass is not in the same pro'ess, an" may not e!en be knoAn by name to the 'lient. When you "e&ine a ser!i'e to be use" by remote, you nee" to a"" an intent&ilter element to your ser!i'e "e'laration in the mani&est, in"i'ating hoA you Aant that ser!i'e to be re&erre" to by 'lients. 8he mani&est &or =emoteService is shoAn beloA,
&'%ml version()$.*) encoding()utf-+)', &manifest android/versionCode()$) android/version9ame()$.*) package()com.commonsware.android.advservice) %mlns/android()0ttp/""sc0emas.android.com"apk"res"android), &uses-sdk android/minSdkVersion()O) android/targetSdkVersion()N) ", &supports-screens android/largeScreens()false) android/normalScreens()true) android/smallScreens()false) ", &application android/icon()2drawable"cw) android/label()2string"app1name), &service android/name().7s0Service), &intent-filter, &action android/name()com.commonsware.android.advservice.IScript) ", &"intent-filter, &"service, &"application, &"manifest,

+ere, Ae say that the ser!i'e 'an be i"enti&ie" by the name com.commonsware.android.advservice.IScript. %o long as the 'lient uses this name to i"enti&y the ser!i'e, it 'an bin" to that ser!i'e:s A#0.

'37
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

0n this 'ase, the name is not an implementation, but the A0DL A#0, as you Aill see beloA. 0n e&&e't, this means that so long as some ser!i'e e>ists on the "e!i'e that implements this A#0, the 'lient Aill be able to bin" to something.

The Service
1eyon" the mani&est, the ser!i'e implementation is not too unusual. 8here is the A0DL inter&a'e, IScript,
package com.commonsware.android.advservice5 "" >eclare t0e interface. interface IScript ; void e(ecuteScript String script!5 A

An" there is the a'tual ser!i'e 'lass itsel&, 7s0Service,


package com.commonsware.android.advservice5 import import import import import android.app.Service5 android.content.Intent5 android.os.I7inder5 android.util.-og5 bs0.Interpreter5

public class 7s0Service e%tends Service ; private final IScript.Stub binder(new IScript.Stub ! ; public void e(ecuteScript String script! ; e(ecuteScriptImpl script!5 A A5 private Interpreter i(new Interpreter !5 24verride public void onCreate ! ; super.onCreate !5 tr. ; i.set )conte%t)@ t0is!5 A catc0 bs0.:val:rror e! ; -og.e )7s0Service)@ ):rror e%ecuting script)@ e!5 A

'58
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

24verride public I7inder onBind Intent intent! ; return binder!5 A 24verride public void on"estroy ! ; super.on"estroy !5 A private void e(ecuteScriptImpl String script! ; tr. ; i.eval script!5 A catc0 bs0.:val:rror e! ; -og.e )7s0Service)@ ):rror e%ecuting script)@ e!5 A A

0& you ha!e seen the ser!i'e an" 1eanshell samples in The Busy Coder's Guide to Android Deve opment then this implementation Aill seem &amiliar. 8he biggest thing to note is that the ser!i'e returns no result an" han"les any errors lo'ally. +en'e, the 'lient Aill not get any response ba'k &rom the s'ript O the s'ript Aill Nust run. 0n a real implementation, this Aoul" be silly, an" Ae Aill Aork to re'ti&y this later in this 'hapter. Also note that, in this implementation, the s'ript is e>e'ute" "ire'tly by the ser!i'e on the 'alling threa". Fne might think this is not a problem, sin'e the ser!i'e is in its oAn pro'ess an", there&ore, 'annot possibly be using the 'lient:s $0 threa". +oAe!er, A0DL 0#C 'alls are syn'hronous, so the 'lient Aill still blo'k Aaiting &or the s'ript to be e>e'ute". 8his too Aill be 'orre'te" later in this 'hapter.

The Client
8he 'lient O 7s0Service>emo out o& 6dvServices"=emoteClient O is a &airly straight-&orAar" mashup o& the ser!i'e an" 1eanshell 'lients, Aith tAo tAists,
package com.commonsware.android.advservice.client5 import android.app.6ctivit.5

'5/
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

import import import import import import import import import import import

android.app.6lert>ialog5 android.content.Component9ame5 android.content.Conte%t5 android.content.Intent5 android.content.ServiceConnection5 android.os.7undle5 android.os.I7inder5 android.view.View5 android.widget.7utton5 android.widget.:dit?e%t5 com.commonsware.android.advservice.IScript5

public class 7s0Service>emo e%tends 6ctivit. ; private IScript service(null5 private ServiceConnection svcConn(new ServiceConnection ! ; public void onServiceConnected Component9ame class9ame@ I7inder binder! ; service(IScript.Stub.asInterface binder!5 A public void onService"isconnected Component9ame class9ame! ; service(null5 A A5 24verride public void onCreate 7undle icicle! ; super.onCreate icicle!5 setContentView =.la.out.main!5 7utton btn( 7utton!findViewById =.id.eval!5 final :dit?e%t script( :dit?e%t!findViewById =.id.script!5 btn.set$nClic)Listener new View.$nClic)Listener ! ; public void onClic) View view! ; String src(script.get+e(t !.toString !5 tr. ; service.e(ecuteScript src!5 A catc0 android.os.=emote:%ception e! ; 6lert>ialog.7uilder builder( new 6lert>ialog.Builder 7s0Service>emo.t0is!5 builder .set+itle ):%ceptionM)! .set'essage e.toString !! .set ositiveButton )4U)@ null! .s!ow !5 A A!5 A

bindService new Intent )com.commonsware.android.advservice.IScript)!@

'5'
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

svcConn@ Conte%t.7I9>16E?41C=:6?:!5 A 24verride public void on"estroy ! ; super.on"estroy !5 A A unbindService svcConn!5

Fne tAist is that the 'lient nee"s its oAn 'opy o& IScript.aidl. A&ter all, it is a totally separate appli'ation, an" there&ore "oes not share sour'e 'o"e Aith the ser!i'e. 0n a pro"u'tion en!ironment, Ae might 'ra&t an" "istribute a -A &ile that 'ontains the IScript 'lasses, so both 'lient an" ser!i'e 'an Aork o&& the same "e&inition (see the up'oming 'hapter on reusable 'omponents). *or noA, Ae Aill Nust ha!e a 'opy o& the A0DL. 8hen, the bindService ! 'all uses a slightly "i&&erent Intent, one that re&eren'es the name the ser!i'e is registere" un"er, an" that is the glue that alloAs the 'lient to &in" the mat'hing ser!i'e. 0& you 'ompile both appli'ations an" uploa" them to the "e!i'e, then start up the 'lient, you 'an enter in 1eanshell 'o"e an" ha!e it be e>e'ute" by the ser!i'e. 2ote, though, that you 'annot per&orm $0 operations (e.g., raise a ?oast) &rom the ser!i'e. 0& you 'hoose some s'ript that is long-running, you Aill see that the ;o= button is blo'ke" until the s'ript is 'omplete,

'50
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

#igure 382 The Bsh"ervice=emo application, running a long script

"ervicin# the "ervice


8he pre'e"ing se'tion outline" tAo &laAs in the implementation o& the 1eanshell remote ser!i'e, 1. 8he 'lient re'ei!e" no results &rom the s'ript e>e'ution

2. 8he 'lient blo'ke" Aaiting &or the s'ript to 'omplete 0& Ae Aere not Aorrie" about the blo'king-'all issue, Ae 'oul" simply ha!e the e%ecuteScript ! e>porte" A#0 return some sort o& result (e.g., toString ! on the result o& the 1eanshell eval ! 'all). +oAe!er, that Aoul" not sol!e the &a't that 'alls to ser!i'e A#0s are syn'hronous e!en &or remote ser!i'es. Another approa'h Aoul" be to pass some sort o& 'allba'k obNe't Aith e%ecuteScript !, su'h that the ser!er 'oul" run the s'ript asyn'hronously an" in!oke the 'allba'k on su''ess or &ailure. 8his, though, implies that there is some Aay to ha!e the a'ti!ity e>port an A#0 to the ser!i'e.

'5&
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

*ortunately, this is eminently "oable, as you Aill see in this se'tion, an" the a''ompanying samples (6dvServices"=emoteService:% an" 6dvServices"=emoteClient:%).

Callbac*s via AI$/


A0DL "oes not ha!e any 'on'ept o& "ire'tion. 0t Nust knoAs inter&a'es an" stub implementations. 0n the pre'e"ing e>ample, Ae use" A0DL to ha!e the ser!i'e &lesh out the stub implementation an" ha!e the 'lient a''ess the ser!i'e !ia the A0DL-"e&ine" inter&a'e. +oAe!er, there is nothing magi' about ser!i'es implementing an" 'lients a''essing O it is e?ually possible to re!erse matters an" ha!e the 'lient implement something the ser!i'e uses !ia an inter&a'e. %o, &or e>ample, Ae 'oul" 'reate an IScript=esult.aidl &ile,
package com.commonsware.android.advservice5 "" >eclare t0e interface. interface IScript=esult ; void success String result!5 void failure String error!5 A

8hen, Ae 'an augment IScript itsel&, to pass an IScript=esult Aith


e%ecuteScript !,
package com.commonsware.android.advservice5 import com.commonsware.android.advservice.IScript=esult5 "" >eclare t0e interface. interface IScript ; void e(ecuteScript String script@ IScript=esult cb!5 A

2oti'e that Ae nee" to spe'i&i'ally import IScript=esult, Nust like Ae might import some GregularG -a!a inter&a'e. An", as be&ore, Ae nee" to make sure the 'lient an" the ser!er are Aorking o&& o& the same A0DL "e&initions, so these tAo A0DL &iles nee" to be repli'ate" a'ross ea'h proNe't.

'51
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

1ut other than that one little tAist, this is all that is re?uire", at the A0DL le!el, to ha!e the 'lient pass a 'allba'k obNe't to the ser!i'e, "e&ine the A0DL &or the 'allba'k an" a"" it as a parameter to some ser!i'e A#0 'all. F& 'ourse, there is a little more Aork to "o on the 'lient an" ser!er si"e to make use o& this 'allba'k obNe't.

Revising the Client


Fn the 'lient, Ae nee" to implement an IScript=esult. Fn success !, Ae 'an "o something like raise a ?oastP on failure !, Ae 'an perhaps shoA an 6lert>ialog. 8he 'at'h is that Ae 'annot be 'ertain Ae are being 'alle" on the $0 threa" in our 'allba'k obNe't. %o, the sa&est Aay to "o that is to make the 'allba'k obNe't use something like run4nEi?0read ! to ensure the results are "isplaye" on the $0 threa",
private final IScript=esult.Stub callback(new IScript=esult.Stub ! ; public void success final String result! ; run$nUi+!read new Runnable ! ; public void run ! ; successImpl result!5 A A!5 A public void failure final String error! ; run$nUi+!read new Runnable ! ; public void run ! ; failureImpl error!5 A A!5 A A5 private void successImpl String result! ; ?oast .ma)e+e(t 7s0Service>emo.t0is@ result@ ?oast.-:9#?C1-49#! .s!ow !5 A private void failureImpl String error! ;

'53
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

6lert>ialog.7uilder builder( new 6lert>ialog.Builder 7s0Service>emo.t0is!5 builder .set+itle ):%ceptionM)! .set'essage error! .set ositiveButton )4U)@ null! .s!ow !5

An", o& 'ourse, Ae nee" to up"ate our 'all to e%ecuteScript ! to pass the 'allba'k obNe't to the remote ser!i'e,
24verride public void onCreate 7undle icicle! ; super.onCreate icicle!5 setContentView =.la.out.main!5 7utton btn( 7utton!findViewById =.id.eval!5 final :dit?e%t script( :dit?e%t!findViewById =.id.script!5 btn.set$nClic)Listener new View.$nClic)Listener ! ; public void onClic) View view! ; String src(script.get+e(t !.toString !5 tr. ; service.e(ecuteScript src@ callback!5 A catc0 android.os.=emote:%ception e! ; failureImpl e.toString !!5 A A A!5 bindService new Intent )com.commonsware.android.advservice.IScript)!@ svcConn@ Conte%t.7I9>16E?41C=:6?:!5

Revising the Service


8he ser!i'e also nee"s 'hanging, to both e>e'ute the s'ripts asyn'hronously an" use the supplie" 'allba'k obNe't &or the en" results o& the s'ript:s e>e'ution.
7s0Service &rom 6dvServices"=emoteService:% uses the -inked7locking[ueue pattern to manage a ba'kgroun" threa". An :%ecuteScriptJob Araps up the s'ript an" 'allba'kP Ahen the Nob is e!entually pro'esse", it uses the
'55
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

'allba'k to supply the results o& the eval ! (on su''ess) or the message o& the :%ception (on &ailure),
package com.commonsware.android.advservice5 import import import import import import android.app.Service5 android.content.Intent5 android.os.I7inder5 android.util.-og5 java.util.concurrent.-inked7locking[ueue5 bs0.Interpreter5

public class 7s0Service e%tends Service ; private final IScript.Stub binder(new IScript.Stub ! ; public void e(ecuteScript String script@ IScript=esult cb! ; e(ecuteScriptImpl script@ cb!5 A A5 private Interpreter i(new Interpreter !5 private -inked7locking[ueue&Job, B(new -inked7locking[ueue&Job, !5 24verride public void onCreate ! ; super.onCreate !5 new +!read B<rocessor!.start !5 tr. ; i.set )conte%t)@ t0is!5 A catc0 bs0.:val:rror e! ; -og.e )7s0Service)@ ):rror e%ecuting script)@ e!5 A A 24verride public I7inder onBind Intent intent! ; return binder!5 A 24verride public void on"estroy ! ; super.on"estroy !5 B.add new #illJob !!5 A private void e(ecuteScriptImpl String script@ IScript=esult cb! ; B.add new E(ecuteScriptJob script@ cb!!5 A =unnable B<rocessor(new Runnable ! ;

'56
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

public void run ! ; w0ile true! ; tr. ; Job j(B.ta)e !5 if j.stop+!read !! ; break5

A else ; j.process !5 A A catc0 Interrupted:%ception e! ; break5 A A A5 class Job ; boolean stop+!read ! ; return false!5 A void process ! ; "" no-op A A class UillJob e%tends Job ; 24verride boolean stop+!read ! ; return true!5 A A class :%ecuteScriptJob e%tends Job ; IScript=esult cb5 String script5 E(ecuteScriptJob String script@ IScript=esult cb! ; t0is.script(script5 t0is.cb(cb5 A void process ! ; tr. ; cb.success i.eval script!.toString !!5 A catc0 ?0rowable e! ; -og.e )7s0Service)@ ):rror e%ecuting script)@ e!5 tr. ; cb.failure e.get'essage !!5 A

'57
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

A A A A

A catc0 ?0rowable t! ; -og.e )7s0Service)@ ):rror returning e%ception to client)@ t!5 A

2oti'e that the ser!i'e:s oAn A#0 Nust nee"s the IScript=esult parameter, Ahi'h 'an be passe" aroun" an" use" like any other -a!a obNe't. 8he &a't that it happens to 'ause 'alls to be ma"e syn'hronously ba'k to the remote 'lient is in!isible to the ser!i'e. 8he net result is that the 'lient 'an 'all the ser!i'e an" get its results Aithout tying up the 'lient:s $0 threa". Bou may be Aon"ering Ahy Ae "o not simply use an 6s.nc?ask. 8he reason is that remote ser!i'e metho"s e>pose" by A0DL are not in!oke" on the main appli'ation threa" O one o& the &eA pla'es in An"roi" Ahere An"roi" 'alls your 'o"e &rom a ba'kgroun" threa". An 6s.nc?ask e>pe'ts to be 'reate" on the main appli'ation threa".

The Bind That 5ails


%ometimes, a 'all to bindService ! Aill &ail &or some reason. 8he most 'ommon 'ause Aill be an in!ali" Intent O &or e>ample, you might be trying to bin" to a Service that you &aile" to register in the mani&est. 8he bindService ! metho" returns a boolean !alue in"i'ating Ahether or not there Aas an imme"iate problem, so you 'an take appropriate steps. *or lo'al ser!i'es, this is usually Nust a 'o"ing problem. *or remote ser!i'es, though, it 'oul" be that the ser!i'e you are trying to Aork Aith has not been installe" on the "e!i'e. Bou ha!e tAo approa'hes &or "ealing Aith this, 1. Bou 'an Aat'h &or bindService ! to return false an" assume that means the ser!i'e is not installe"

'68
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

2. Bou 'an use introspe'tion to see i& the ser!i'e is in"ee" installe" be&ore you e!en try 'alling bindService ! We Aill look at introspe'tion te'hni?ues later in this book.

$* the Bindin# $s Too Ti#ht


%ometimes, bin"ing is more than you really nee". %en"ing "ata to a remote ser!i'e is easy, e!en Aithout bin"ing. -ust pa'kage some "ata in Intent e>tras an" use that Intent in a startService ! 'all. 8he remote ser!i'e 'an grab those e>tras an" operate on that "ata. 8his Aorks best Aith an IntentService, Ahi'h "oes three things to assist Aith this pattern, 1. 0t passes the Intents, Aith their e>tras, to your 'o"e in onCandleIntent ! on a ba'kgroun" threa", so you 'an take as long as you Aant to pro'ess them

2. 0t ?ueues up Intents, so i& another one arri!es Ahile you are Aorking on a pre!ious one, there is no problem /. 0t automati'ally shuts "oAn the ser!i'e Ahen there is no more Aork to be "one 8he biggest issue is getting results ba'k to the 'lient. 8here is no possibility o& a 'allba'k i& there is no bin"ing. *ortunately, An"roi" o&&ers some alternati!es that Aork ni'ely Aith this approa'h.

Private )roadcasts
8he 'on'ept o& a Gpri!ate broa"'astG may seem like an o>ymoron, but it is something a!ailable to you in An"roi".

'6/
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

%en"ing a broa"'ast Intent is &airly easy O 'reate the Intent an" 'all send7roadcast !. +oAe!er, by "e&ault, any appli'ation 'oul" &iel" a 7roadcast=eceiver to Aat'h &or your broa"'ast. 8his may or may not 'on'ern you. 0& you &eel that GspiesG 'oul" be troublesome, you 'an 'all set<ackage ! on your Intent, to limit the "istribution o& the broa"'ast. With set<ackage !, only 'omponents in the name" appli'ation Aill be able to re'ei!e the broa"'ast. Bou 'an e!en arrange to sen" the name o& the pa'kage !ia an e>tra to the remote ser!i'e, so the ser!i'e "oes not nee" to knoA the name o& the pa'kage in a"!an'e.

Pending Results
Another Aay &or a remote ser!i'e to sen" "ata ba'k to your a'ti!ity is !ia create<ending=esult !. 8his is a metho" on 6ctivit. that gi!es you a <endingIntent set up to trigger on6ctivit.=esult ! in your a'ti!ity. 0n essen'e, this is the un"erpinnings behin" start6ctivit.Jor=esult ! an" set=esult !. Bou 'reate the <endingIntent Aith create<ending=esult ! an" pass it in an Intent e>tra to the remote ser!i'e. 8he remote ser!i'e 'an 'all send ! on the <endingIntent, supplying an Intent Aith return "ata, Nust like set=esult ! Aoul" "o in an a'ti!ity starte" !ia start6ctivit.Jor=esult !. 0n your a'ti!ity:s on6ctivit.=esult !, you Aoul" get an" inspe't the returne" Intent. 8his Aorks ni'ely &or a'ti!ities, but this me'hanism "oes not Aork &or other 'omponents. +en'e, you 'annot use this te'hni?ue &or one ser!i'e 'alling another remote ser!i'e, &or e>ample.

)shService2 Revisited
Let us take a 'loser look at those tAo te'hni?ues, as implemente" in 6dvServices"=emoteClientEnbound an" 6dvServices"=emoteServiceEnbound. 8hese !ersions o& the 1eanshell sample are "esigne" to "emonstrate both pri!ate broa"'asts an" pen"ing results.

'6'
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

;larm:anager@ :aking the "ervices Cun .n Time


A 'ommon ?uestion Ahen "oing An"roi" "e!elopment is GAhere "o 0 set up cron NobsJG 8he cron utility O popular in Linu> O is a Aay o& s'he"uling Aork to be "one perio"i'ally. Bou tea'h cron Ahat to run an" Ahen to run it (e.g., Aeek"ays at noon), an" cron takes 'are o& the rest. %in'e An"roi" has a Linu> kernel at its heart, one might think that cron might literally be a!ailable. While cron itsel& is not, An"roi" "oes ha!e a system ser!i'e name" 6larm8anager Ahi'h &ills a similar role. Bou gi!e it a <endingIntent an" a time (an" optionally a perio" &or repeating) an" it Aill &ire o&& the Intent as nee"e". 1y this me'hanism, you 'an get a similar e&&e't to cron. 8here is one small 'at'h, though, An"roi" is "esigne" to run on mobile "e!i'es, parti'ularly ones poAere" by all-too-tiny batteries. 0& you Aant your perio"i' tasks to be run e!en i& the "e!i'e is GasleepG, you Aill nee" to take a &air number o& e>tra steps, mostly stemming aroun" the 'on'ept o& the Wake-ock.

The 'a?e*ul$ntent"ervice Pattern


Most times, i& you are bothering to get 'ontrol on a perio"i' basis, you Aill Aant to "o so e!en Ahen the "e!i'e is asleep. *or e>ample, i& you are Ariting an email 'lient, you Aill Aant to go get neA emails e!en i& the "e!i'e is asleep, so the user has all o& the emails imme"iately upon the ne>t time the "e!i'e Aakes up. Bou might e!en Aant to raise a 9otification base" upon the arri!e" emails. Alarms that Aake up the "e!i'e are possible, but tri'ky, so Ae Aill e>amine 6larm8anager in the 'onte>t o& this s'enario. An", to make that Aork, Ae are going to use the WakefulIntentService O another o& the CommonsWare An"roi" Components, a!ailable as open sour'e &or you to use. 0n parti'ular, Ae Aill be looking at the "emo proNe't &rom the WakefulIntentService
'60
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

;it+ub proNe't, in a""ition to the implementation o& WakefulIntentService itsel&, spe'i&i'ally looking at these &rom the stan"point o& using 6larm8anager &or s'he"ule" tasks. 2ote that to use WakefulIntentService you Aill nee" the W6U:1-4CU permission in your appli'ation, an" i& you are using the 6larm-istener approa'h "es'ribe" in this 'hapter, you Aill also nee" the =:C:IV:1744?1C48<-:?:> permission.

Step 345 Create an Alar

/istener

8he WakefulIntentService o&&ers an 6larm-istener inter&a'e. 0& you 'reate one an" register it properly, the WakefulIntentService Aill han"le mu'h o& the "etails o& arranging to s'he"ule your alarms Ahene!er they nee" to be s'he"ule", plus "o the a'tual perio"i' Aork that you nee" the alarms &or. An 6larm-istener nee"s to implement three metho"s,
sc0edule6larms !,

Ahi'h is Ahere you Aill tea'h An"roi" Ahen an alarm is suppose" to go o&&
sendWakefulWork !, get8a%6ge !,

Ahi'h is Ahere you tell WakefulIntentService Ahat shoul" o''ur Ahen an alarm goes o&& Ahere you in"i'ate hoA long o& a time betAeen alarms shoul" elapse be&ore WakefulIntentService assumes that the alarms Aere lost an" nee" to be re-s'he"ule"

*or e>ample, &rom the WakefulIntentService "emo proNe't, here is an 6larm-istener implementation name" 6pp-istener,
package com.commonsware.cwac.wakeful.demo5 import import import import import android.app.6larm8anager5 android.app.<endingIntent5 android.content.Conte%t5 android.os.S.stemClock5 com.commonsware.cwac.wakeful.WakefulIntentService5

public class 6pp-istener implements WakefulIntentService.6larm-istener ; public void sc!edule*larms 6larm8anager mgr@ <endingIntent pi@

'6&
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

Conte%t ct%t! ; mgr.setIne(actRepeating 6larm8anager.:-6<S:>1=:6-?I8:1W6U:E<@ S.stemClock.elapsedRealtime !3N****@ 6larm8anager.I9?:=V6-1JIJ?::918I9E?:S@ pi!5

public void send.a)eful.or) Conte%t ct%t! ; WakefulIntentService.send.a)eful.or) ct%t@ 6ppService.class!5 A public long get'a(*ge ! ; return 6larm8anager.I9?:=V6-1JIJ?::918I9E?:S*F!5 A A

Bour sc0edule6larms ! metho" Aill be passe" e!erything you shoul" nee" to "e&ine Ahen you Aant to get 'ontrol again in the &uture. Mostly, this is in the &orm o& an 6larm8anager, to sa!e you &rom ha!ing to 'all getS.stemService ! on a Conte%t to get an 6larm8anager instan'e. 6larm8anager has three metho"s &or "e&ining Ahen your s'he"ule" tasks shoul" run,
set=epeating !,

Ahere you stipulate Ahen the &irst time is you Aant your task to run, an" hoA &re?uently therea&ter
setIne%act=epeating !, Ahi'h "oes set !,

the same thing but gi!es An"roi" the &le>ibility to slightly tAeak your s'he"ule &or more e&&i'ien'y Ahi'h is &or Gone-shotG alarms, Ahere you Aant a task to run on'e at a "esignate" time

8he 6larm-istener pattern is &or use Aith the &irst tAo approa'hes, not &or one-shot alarms !ia set !. @a'h o& these metho"s takes a GtypeG o& alarm. 8here are &our types, base" upon tAo orthogonal a>es o& "e'ision,

Do you Aant the "e!i'e to Aake up out o& sleep mo"e to per&orm the taskJ Do you Aant to spe'i&y the time &or the &irst task in terms o& a'tual real Aorl" time, or simply an amount o& time &rom noAJ

'61
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

8here are &our !alues, there&ore, you 'an 'hoose &rom &or the &irst parameter,
:-6<S:>1=:6-?I8: in"i'ates you Aant to spe'i&y a time relati!e to S.stemClock.elapsed=ealtime ! (a goo" 'hoi'e &or spe'i&ying a time

relati!e to noA), an" you "o not Aant to Aake up the "e!i'e &or the alarms

is the same as the abo!e one, e>'ept that you "o Aant the "e!i'e to Aake up out o& sleep mo"e
:-6<S:>1=:6-?I8:1W6U:E< =?C in"i'ates that you Aant to S.stem.current?ime8illis ! (a goo"

spe'i&y a time relati!e to 'hoi'e &or spe'i&ying a realAorl" time, as you 'an get a suitable !alue &or this out o& a Calendar obNe't), an" you "o not Aant to Aake up the "e!i'e &or the alarms is the same as the abo!e one, e>'ept that you "o Aant the "e!i'e to Aake up out o& sleep mo"e
=?C1W6U:E<

%o, in the abo!e sample, Ae are using setIne%act=epeating !, in"i'ating that Ae Aant the &irst e!ent to o''ur one minute (50,000 millise'on"s) &rom noA, then re'ur e!ery 16 minutes or so. 8he metho" is Ahere you in"i'ate to is to be "one Ahen ea'h alarm goes o&&. Most times, you Aill simply turn aroun" an" 'all sendWakefulWork ! on WakefulIntentService itsel&, i"enti&ying your 'ustom sub'lass o& WakefulIntentService, Ahere your business logi' Aill resi"e. 0n the abo!e sample, our business logi' is in 6ppService, Ahi'h Ae Aill e>amine shortly.
sendWakefulWork ! WakefulIntentService Ahat

8he get8a%6ge ! metho"... takes a bit o& e>plaining, Ahi'h Ae Aill "o later in this 'hapter. *or the moment, take it on &aith that a !alue o& tAi'e your perio" is a reasonable approa'h.

Register the Alar Receiver


8he WakefulIntentService library supplies a 'lass name" 6larm=eceiver. Bou Aill nee" to a"" this to your mani&est !ia a &receiver, element, to get

'63
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

'ontrol Ahen the "e!i'e Aakes up. *or e>ample, here is the mani&est &rom the "emo proNe't,
&'%ml version()$.*) encoding()utf-+)', &manifest %mlns/android()0ttp/""sc0emas.android.com"apk"res"android) package()com.commonsware.cwac.wakeful.demo) android/versionCode()G) android/version9ame()$.*) android/install-ocation()auto), &uses-sdk android/minSdkVersion()O) android/targetSdkVersion()N)", &supports-screens android/largeScreens()false) android/normalScreens()true) android/smallScreens()false)", &uses-permission android/name()android.permission.=:C:IV:1744?1C48<-:?:>)", &uses-permission android/name()android.permission.W6U:1-4CU)", &application android/label()2string"app1name), &receiver android/name()com.commonsware.cwac.wakeful.6larm=eceiver), &intent-filter, &action android/name()android.intent.action.744?1C48<-:?:>)", &"intent-filter, &meta-data android/name()com.commonsware.cwac.wakeful) android/resource()2%ml"wakeful)", &"receiver, &service android/name().6ppService), &"service, &activit. android/label()2string"app1name) android/name().>emo6ctivit.) android/t0eme()2android/st.le"?0eme.9o>ispla.), &intent-filter, &action android/name()android.intent.action.86I9)", &categor. android/name()android.intent.categor..-6E9CC:=)", &"intent-filter, &"activit., &"application, &"manifest,

Fur &receiver, points to the com.commonsware.cwac.wakeful.6larm=eceiver 'lass an" ties it to a 744?1C48<-:?:> a'tion. 8his re?uires a &uses-permission,
'65
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

element to re?uest the =:C:IV:1744?1C48<-:?:> permission, so users Aill knoA at install time that Ae nee" to get 'ontrol Ahen the "e!i'e turns on. Fur &receiver, element also has a &meta-data, element. 8hese elements are use" to supply more in&ormation about a 'omponent than the mani&est IML 'alls &or. 0n our 'ase, Ae are in"i'ating that there is a""itional "ata, knoAn as com.commonsware.cwac.wakeful, a!ailable !ia a wakeful IML resour'e ("res"%ml"wakeful.%ml). 8hat resour'e 'ontains a single WakefulIntentService element,
&WakefulIntentService listener()com.commonsware.cwac.wakeful.demo.6pp-istener) ",

8he one attribute in that element, listener, points to our 6larm-istener implementation &rom the pre!ious step.

Step 365 $o 7our Wa*eful Wor*


Fur 6ppService Aill get 'ontrol in a metho" name" doWakefulWork !. 8he doWakefulWork ! metho" has similar semanti's to the onCandleIntent ! o& a regular IntentService O Ae get 'ontrol in a ba'kgroun" threa", an" the ser!i'e Aill shut "oAn on'e the metho" returns i& there is no other outstan"ing Aork. 8he "i&&eren'e is that WakefulIntentService Aill keep the "e!i'e aAake Ahile doWakefulWork ! is "oing its Aork. 0n this 'ase, 6ppService Nust logs a message to LogCat,
package com.commonsware.cwac.wakeful.demo5 import android.content.Intent5 import android.util.-og5 import com.commonsware.cwac.wakeful.WakefulIntentService5 public class 6ppService e%tends WakefulIntentService ; public *ppService ! ; super )6ppService)!5 A 24verride protected void do.a)eful.or) Intent intent! ;

'66
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

-og.i )6ppService)@ )ITm awakeM ITm awakeM A A

.awn!)!5

An" that:s it. 8hose tAo steps O plus WakefulIntentService O is all you nee" to get 'ontrol on a perio"i' basis to "o Aork, Aaking up the phone as nee"e". F& 'ourse, Ae ha!e not yet s'he"ule" any alarms. 8o un"erstan" hoA to "o that, Ae nee" to &irst un"erstan" when to "o that.

'hen Alarms Come and Go


When your app is initially installe" by the user, none o& your 'o"e is imme"iately e>e'ute". +en'e, you Aill not ha!e ha" a 'han'e to register any alarms. %o, the &irst pla'e you nee" to think about registering your alarms is Ahen your laun'her a'ti!ity is e>e'ute". 0n the WakefulIntentService "emo, there is a >emo6ctivit. that "oes Nust that,
package com.commonsware.cwac.wakeful.demo5 import import import import import android.app.6ctivit.5 android.os.7undle5 android.os.Strict8ode5 android.widget.?oast5 com.commonsware.cwac.wakeful.WakefulIntentService5

public class >emo6ctivit. e%tends 6ctivit. ; 24verride public void onCreate 7undle savedInstanceState! ; super.onCreate savedInstanceState!5 Strict8ode.set+!read olicy new Strict8ode.?0read<olic..Builder ! .detect*ll ! .penaltyLog ! .build !!5 WakefulIntentService.sc!edule*larms new *ppListener !@ t0is@ false!5 ?oast.ma)e+e(t t0is@ )6larms activeM)@ ?oast.-:9#?C1-49#!.s!ow !5 finis! !5

'67
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

A A

8he sc0edule6larms ! metho" on WakefulIntentService takes an implementation o& your 6larm-istener, a Conte%t, an" an optional boolean &lag in"i'ating Ahether or not the alarms shoul" be &or'e" to be s'he"ule", e!en i& they probably are alrea"y a'ti!e. 1y "e&ault, this is set to true, though our >emo6ctivit. has it as false. %o, the &irst time your a'ti!ity is e>e'ute", the alarms Aill be s'he"ule", &olloAing the rules set "oAn in your 6larm-istener. 0n an i"eal Aorl", this is all you Aoul" nee". 0& this Aere an i"eal Aorl", though, this part o& the book Aoul" not nee" to be Aritten. %in'e you are rea"ing it, you 'an tell that this is not an i"eal Aorl". %o, Ahen else "o Ae nee" to s'he"ule alarmsJ

+n a Reboot
A $ni>-style 'ron "aemon Aill pi'k up Nobs Ahere it le&t o&& a&ter a reboot. %imilarly, Win"oAs G%'he"ule" 8asksG Aill resume a&ter a reboot. Fn the other han", 6larm8anager in An"roi" is Aipe" 'lean, starting Aith Cero s'he"ule" alarms. 8he argument that Ae ha!e been gi!en is that the 'ore An"roi" team "oes not Aant apps to s'he"ule alarms an" G&orgetG about them, 'ausing them to pile up an" sloA "oAn the "e!i'e. While this is a noble obNe'ti!e, it "oes 'ause some annoyan'e, as Ae nee" to get 'ontrol at boot time an" arrange to res'he"ule the alarms.

After )eing Force,Stopped


$sers 'an go into the %ettings appli'ation, &in" your appli'ation, an" 'li'k a G*or'e %topG button. When they "o this, your app mo!es into a Gstopppe"G state. 2othing o& your 'o"e Aill run again O in'lu"ing any 7roadcast=eceiver 'omponents that you ha!e "e&ine" O until the user proa'ti!ely runs one o& your a'ti!ities again, typi'ally &rom the laun'her. +en'e, any user that
'78
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

&or'e-stops your app Aill 'ause you to not re'ei!e any s'he"ule" alarms e!er again, as the e>isting alarms are remo!e" an" you Aill not be able to get 'ontrol again at boot time. 8his is Ahy Ae are looking at s'he"uling the alarms e!ery time the >emo6ctivit. runs. 2ot only might it be the !ery &irst time the user has laun'he" our a'ti!ity, but it might be the !ery &irst time the user has laun'he" our a'ti!ity a&ter being &or'e-stoppe". *ortunately, WakefulIntentService han"les these s'enarios &or you, so long as you 'all sc0edule6larms ! Ahene!er your app is laun'he". 8his is Ahere get8a%6ge ! 'omes into play O i& WakefulIntentService "ete'ts that an alarm has not gone o&& in the number o& millise'on"s you return &rom get8a%6ge !, it assumes that the user &or'e-stoppe" your appli'ation an" it s'he"ules the alarms again.

The :'a?e*ul: o* 'a?e*ul$ntent"ervice


2oA, let us take a look Gun"er the 'o!ersG to see hoA WakefulIntentService a'tually keeps the "e!i'e aAake long enough &or doWakefulWork ! to "o its, um, Aake&ul Aork.

Concept of Wa*e/oc*s
Most o& the time in An"roi", you are "e!eloping 'o"e that Aill run Ahile the user is a'tually using the "e!i'e. A'ti!ities, &or e>ample, only really make sense Ahen the "e!i'e is &ully aAake an" the user is tapping on the s'reen or keyboar". #arti'ularly Aith s'he"ule" ba'kgroun" tasks, though, you nee" to bear in min" that the "e!i'e Aill e!entually Ggo to sleepG. 0n &ull sleep mo"e, the "isplay, main C#$, an" keyboar" are all poAere" o&&, to ma>imiCe battery li&e. Fnly on a loA-le!el system e!ent, like an in'oming phone 'all, Aill anything Aake up.

'7/
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

Another thing that Aill partially Aake up the phone is an Intent raise" by the 6larm8anager. %o long as broa"'ast re'ei!ers are pro'essing that Intent, the 6larm8anager ensures the C#$ Aill be running (though the s'reen an" keyboar" are still o&&). Fn'e the broa"'ast re'ei!ers are "one, the 6larm8anager lets the "e!i'e go ba'k to sleep. Bou 'an a'hie!e the same e&&e't in your 'o"e !ia a Wake-ock, obtaine" !ia the <ower8anager system ser!i'e. When you a'?uire a Gpartial Wake-ockG (<6=?I6-1W6U:1-4CU), you pre!ent the C#$ &rom going ba'k to sleep until you release sai" Wake-ock. 1y proper use o& a partial Wake-ock, you 'an ensure the C#$ Aill not get shut o&& Ahile you are trying to "o ba'kgroun" Aork, Ahile still alloAing the "e!i'e to sleep most o& the time, in betAeen alarm e!ents. +oAe!er, using a Wake-ock is a bit tri'ky, parti'ularly Ahen respon"ing to an alarm Intent, as Ae Aill see in the ne>t &eA se'tions.

The Wa*e/oc* Proble


*or a 1W6U:E< alarm, the 6larm8anager Aill arrange &or the "e!i'e to stay aAake, !ia a Wake-ock, &or as long as the 7roadcast=eceiver:s on=eceive ! metho" is e>e'uting. *or some situations, that may be all that is nee"e". +oAe!er, on=eceive ! is 'alle" on the main appli'ation threa", an" An"roi" Aill kill o&& the re'ei!er i& it takes too long. Bour natural in'lination in this 'ase is to ha!e the 7roadcast=eceiver arrange &or a Service to "o the long-running Aork on a ba'kgroun" threa", sin'e 7roadcast=eceiver obNe'ts shoul" not be starting their oAn threa"s. #erhaps you Aoul" use an IntentService, Ahi'h pa'kages up this Gstart a Service to "o some Aork in the ba'kgroun"G pattern. An", gi!en the pre'e"ing se'tion, you might try a'?uiring a partial Wake-ock at the beginning o& the Aork an" release it at the en" o& the Aork, so the C#$ Aill keep running Ahile your IntentService "oes its thing. 8his strategy Aill Aork...some o& the time.

'7'
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

8he problem is that there is a gap in Wake-ock 'o!erage, as "epi'te" in the &olloAing "iagram,

#igure 3/2 The Wake)ock gap

8he 7roadcast=eceiver Aill 'all startService ! to sen" Aork to the IntentService, but that ser!i'e Aill not start up until a&ter on=eceive ! en"s. As a result, there is a Ain"oA o& time betAeen the en" o& on=eceive ! an" Ahen your IntentService 'an a'?uire its oAn Wake-ock. During that Ain"oA, the "e!i'e might &all ba'k asleep. %ometimes it Aill, sometimes it Aill not. What you nee" to "o, instea", is arrange &or o!erlapping Wake-ock instan'es. Bou nee" to a'?uire a Wake-ock in your 7roadcast=eceiver, "uring the on=eceive ! e>e'ution, an" hol" onto that Wake-ock until the Aork is 'omplete" by the IntentService,

'70
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

#igure 3'2 The Wake)ock overlap

8hen you are assure" that the "e!i'e Aill stay aAake as long as the Aork remains to be "one.

Wa*efulIntentService and Wa*e/oc*s


1y noA, you ha!e noti'e" that the WakefulIntentService re'ipe "oes not ha!e you manage your oAn Wake-ock. 8hat is be'ause WakefulIntentService han"les it &or you. Fne reason Ahy WakefulIntentService e>ists is to manage that Wake-ock, be'ause Wake-ocks su&&er &rom one maNor problem, they are not <arcelable, an" there&ore 'annot be passe" in an Intent e>tra. +en'e, &or our 7roadcast=eceiver an" our WakefulIntentService to use the same Wake-ock, they ha!e to be share" !ia a stati' "ata member... Ahi'h is i'ky. WakefulIntentService is "esigne" to hi"e this i'ky part &rom you, so you "o not ha!e to Aorry about it.

$nside 'a?e*ul$ntent"ervice
With all that behin" us, noA Ae 'an take a look at some pie'es o& hoA WakefulIntentService per&orms its magi'.

'7&
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

scheduleAlar s-.
Fur >emo6ctivit. 'alle" sc0edule6larms !. 8he Nob o& sc0edule6larms ! is to get your 6larm-istener to s'he"ule the alarms, i& it appears that this is ne'essary,
public static void sc!edule*larms 6larm-istener listener@ Conte%t ct%t! ; sc!edule*larms listener@ ct%t@ true!5 A public static void sc!edule*larms 6larm-istener listener@ Conte%t ct%t@ boolean force! ; S0ared<references prefs(ct%t.getS!ared references 968:@ *!5 long last6larm(prefs.getLong -6S?16-6=8@ *!5 if last6larm((* LL force LL S.stem.current+ime'illis !,last6larm ZZ S.stem.current+ime'illis !-last6larm,listener.get'a(*ge !!! ; 6larm8anager mgr( 6larm8anager!ct%t.getSystemService Conte%t.6-6=81S:=VIC:!5 Intent i(new Intent ct%t@ 6larm=eceiver.class!5 <endingIntent pi(<endingIntent.getBroadcast ct%t@ *@ i@ *!5

listener.sc!edule*larms mgr@ pi@ ct%t!5 A A

8he sc0edule6larms ! metho" Aill think that s'he"uling alarms is ne'essary i&,

Bou &or'e" it !ia passing true to the force parameter, or 0& it 'annot &in" the last time the alarm Aent o&&, !ia a !alue store" in a ser!i'e-spe'i&i' S0ared<references obNe't, or 0& the last time the alarm Aent o&& is longer than your "esire" ma>imum age, suggesting that perhaps the user &or'e-stoppe" your app

0n prin'iple, Ae 'oul" Nust alAays s'he"ule the alarms. 0& you 'all set=epeating ! (or kin) on 6larm8anager &or a <endingIntent, any e>isting alarm &or an e?ui!alent <endingIntent is repla'e". +ere, Ge?ui!alentG means that the un"erlying 0ntent has the same a'tion, 'omponent, 'ategories, an" M0M@ type.
'71
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

8he "oAnsi"e o& alAays s'he"uling the alarms is that i& you use set=epeating !, the alarm Aill ne>t go o&& at your "esignate" time, Ahi'h may be &ar sooner than the e>isting alarm Aoul" 'all &or. *or e>ample, suppose that you Aant to get 'ontrol on'e per "ay. 0& you 'all set=epeating ! or setIne%act=epeating ! e!ery time the user laun'hes your main a'ti!ity, you Aill trigger the alarm to go o&& ea'h o& those times, in a""ition to the on'e per "ay. $sing set=epeating ! Aith a spe'i&i' time o& the "ay (e.g., /am) Aill not ha!e that e&&e't, but set=epeating ! Aith G"o the &irst one a minute &rom noAG Aoul".

Alar Receiver
8he WakefulIntentService-supplie" 6larm=eceiver Aill get 'ontrol Ahen the "e!i'e poAers on (!ia our mani&est entry) an" Ahen the alarm goes o&&. At those times, on=eceive ! Aill be 'alle",
24verride public void onReceive Conte%t ct%t@ Intent intent! ; 6larm-istener listener(getListener ct%t!5 listenerM(null! ; intent.get*ction !((null! ; S0ared<references prefs(ct%t.getS!ared references WakefulIntentService.968:@ *!5 if prefs .edit ! .putLong WakefulIntentService.-6S?16-6=8@ S.stem.current+ime'illis !! .commit !5 listener.send.a)eful.or) ct%t!5 A else ; WakefulIntentService.sc!edule*larms listener@ ct%t@ true!5 A if

A A

0& the Intent that Aas broa"'ast "oes not ha!e an a'tion, Ae assume this is the broa"'ast &rom 6larm8anager, an" so Ae 'all sendWakefulWork ! on your 6larm-istener a&ter up"ating our pri!ate S0ared<references to note that the alarm Aent o&& (&or use by sc0edule6larms !). 0&, hoAe!er, the a'tion is not-

'73
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

null, that means Ae are being starte" &rom the 744?1C48<-:?:> broa"'ast, in Ahi'h 'ase Ae 'all sc0edule6larms ! on your 6larm-istener. Where "oes the 6larm-istener obNe't 'ome &romJ A pri!ate get-istener ! metho" that takes a"!antage o& the &meta-data, &rom the mani&est,
2Suppress.arnings )unc0ecked)! private WakefulIntentService.6larm-istener getListener Conte%t ct%t! ; <ackage8anager pm(ct%t.get ac)age'anager !5 Component9ame cn(new Component%ame ct%t@ getClass !!5 tr. ; 6ctivit.Info ai(pm.getReceiverInfo cn@ <ackage8anager.#:?18:?61>6?6!5 Vml=esource<arser %pp(ai.load3ml'eta"ata pm@ W6U:JE-18:?61>6?6!5 w0ile %pp.getEvent+ype !M(Vml<ull<arser.:9>1>4CE8:9?! ; if %pp.getEvent+ype !((Vml<ull<arser.S?6=?1?6#! ; if %pp.get%ame !.equals )WakefulIntentService)!! ; String cls9ame(%pp.get*ttributeValue null@ )listener)!5 Class&6larm-istener, cls( Class&6larm-istener,!Class.for%ame cls9ame!5 return cls.newInstance !!5 A A A

%pp.ne(t !5 A catc0 9ame9otJound:%ception e! ; -og.e getClass !.get%ame !@ )Cannot find own info''')@ e!5 A catc0 Vml<ull<arser:%ception e! ; -og.e getClass !.get%ame !@ )8alformed metadata resource V8-)@ e!5 A catc0 I4:%ception e! ; -og.e getClass !.get%ame !@ )Could not read resource V8-)@ e!5 A catc0 Class9otJound:%ception e! ; -og.e getClass !.get%ame !@ )-istener class not found)@ e!5 A catc0 Illegal6ccess:%ception e! ; -og.e getClass !.get%ame !@ )-istener is not public or lacks public constructor)@ e!5 A catc0 Instantiation:%ception e! ; -og.e getClass !.get%ame !@ )Could not create instance of listener)@ e!5 A

'75
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

return null!5 A

8o rea" "ata &rom a &meta-data, element, you use <ackage8anager to get in&ormation about your 7roadcast=eceiver !ia get=eceiverInfo ! an" the 6ctivit.Info obNe't it returns. Bou 'an ask the 6ctivit.Info obNe't to get you the meta"ata &or a gi!en name !ia the loadVml8eta>ata ! metho", Ahi'h returns an Vml=esource<arser. 8his is an implementation o& the Vml<ull<arser inter&a'e, so you 'an start iterating o!er the parse e!ents until you en'ounter your "esire" element. 0n this 'ase, Ae s'an &or the start-tag e!ent &or the WakefulIntentService element, then rea" out the listener attribute, use Class.for9ame ! to &in" the 'lass, an" 'all newInstance ! on the Class obNe't to 'reate an instan'e o& your 6larm-istener. An alternati!e approa'h Aoul" be to ha!e you sub'lass 6larm=eceiver an" o!erri"e get-istener !, an" you are 'ertainly Ael'ome to "o that i& the &meta-data, approa'h 'auses you "i&&i'ulty. %o, the net o& 6larm=eceiver is that Ae alloA you to s'he"ule your alarms (i& the "e!i'e is &reshly boote") or Ae alloA you to "o your Aake&ul Aork (i& the alarm is &rom 6larm8anager).

Co

and Processing

Ahen triggere" by 6larm8anager, "ete'ts that there is no supplie" a'tion an", in that 'ase, passes 'ontrol to WakefulIntentService !ia sendWakefulWork !. Bou 'an 'all this metho" yoursel& &rom other, non-alarm s'enarios Ahere you Aant Aork to be "one that 'an be 'omplete" Aithout the "e!i'e &alling asleep. 8here are tAo &la!ors o& sendWakefulWork !. 1oth take a Conte%t O the "i&&eren'e is in the se'on" parameter. Fne takes a Class obNe't, i"enti&ying the WakefulIntentService sub'lass that shoul" be in!oke" to "o the Aake&ul Aork. 8his is a 'on!enien'e metho", Arapping aroun" the other &la!or o& sendWakefulWork ! that takes an Intent.

6larm=eceiver,

'76
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

@ither &la!or o& sendWakefulWork ! on WakefulIntentService e!entually routes to a get-ock ! metho",


static final String 968:()com.commonsware.cwac.wakeful.WakefulIntentService)5 static final String -6S?16-6=8()last6larm)5 private static volatile <ower8anager.Wake-ock lockStatic(null5 s.nc0roniKed private static <ower8anager.Wake-ock getLoc) Conte%t conte%t! ; if lockStatic((null! ; <ower8anager mgr( <ower8anager!conte%t.getSystemService Conte%t.<4W:=1S:=VIC:!5 lockStatic(mgr.new.a)eLoc) <ower8anager.<6=?I6-1W6U:1-4CU@ 968:!5 lockStatic.setReferenceCounted true!5 A A return lockStatic!5

public static void send.a)eful.or) Conte%t ct%t@ Intent i! ; getLoc) ct%t.get*pplicationConte(t !!.acquire !5 ct%t.startService i!5 A

8he get-ock ! implementation laCy-'reates our Wake-ock by getting the <ower8anager, 'reating a neA partial Wake-ock, an" setting it to be re&eren'e 'ounte" (meaning i& it is a'?uire" se!eral times, it takes a 'orrespon"ing number o& release ! 'alls to truly release the lo'k). 0& Ae ha!e alrea"y retrie!e" the Wake-ock in a pre!ious in!o'ation, Ae reuse the same lo'k. 1a'k in 6larm=eceiver, up until this point, the C#$ Aas running be'ause 6larm8anager hel" a partial Wake-ock. 2oA, the C#$ is running be'ause both 6larm8anager and WakefulIntentService hol" a partial Wake-ock. 8hen, sendWakefulWork ! starts up our ser!i'e an" e>its. %in'e this is the only thing on=eceive ! Aas "oing in 6larm=eceiver, on=eceive ! e>its. 2otably, 6larm=eceiver "oes not release the Wake-ock it a'?uire" !ia sendWakefulWork !. 8his is important, as Ae nee" to ensure that the ser!i'e 'an get its Aork "one Ahile the C#$ is running. +a" Ae release" the Wake-ock be&ore returning, it is possible that the "e!i'e Aoul" &all ba'k asleep be&ore our ser!i'e ha" a 'han'e to a'?uire a &resh Wake-ock. 8his is one o& the keys o& using Wake-ock su''ess&ully O as nee"e", use o!erlapping

'77
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

instan'es to ensure 'onstant 'o!erage as you pass &rom 'omponent to 'omponent.


Wake-ock

2oA, our ser!i'e Aill start up an" be able to "o something, Ahile the C#$ is running "ue to our a'?uire" Wake-ock. %o, WakefulIntentService Aill noA get 'ontrol, un"er an a'ti!e Wake-ock. %in'e it is an IntentService sub'lass, onCandleIntent ! is 'alle". +ere, Ae Nust route 'ontrol to the sub'lass: implementation o& an abstra't doWakefulWork ! metho", ensuring that Ae release the Wake-ock Ahen the Aork is "one, e!en i& a =untime:%ception is raise",
24verride final protected void on,andleIntent Intent intent! ; tr. ; do.a)eful.or) intent!5 A finall. ; getLoc) t0is.get*pplicationConte(t !!.release !5 A A

As a result, ea'h pie'e o& Aork that gets sent to the WakefulIntentService Aill a'?uire a Wake-ock !ia sendWakefulWork ! an" Aill release that Wake-ock Ahen doWakefulWork ! en"s. Fn'e that Wake-ock is &ully release", the "e!i'e 'an &all ba'k asleep.

Bac?#round Data "ettin#


$sers 'an 'he'k or un'he'k a 'he'kbo> in the %ettings appli'ation that in"i'ates i& they Aant appli'ations to use the 0nternet in the ba'kgroun". %er!i'es employing 6larm8anager shoul" honor this setting. 8o Ahether ba'kgroun" "ata is alloAe", use the system ser!i'e an" 'all get7ackground>ataSetting !. *or e>ample, your alarm-triggere" 7roadcast=eceiver 'oul" 'he'k this be&ore bothering to arrange &or the IntentService (or WakefulIntentService) to "o Aork.
Connectivit.8anager

&in"

out

088
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

7roadcast=eceiver to Aat'h &or the 6C?I49176CU#=4E9>1>6?61S:??I9#1CC69#:> broa"'ast, also "e&ine" on Connectivit.8anager. *or e>ample, you 'oul" ele't to 'ompletely 'an'el your alarm i& the ba'kgroun" "ata setting is &lippe" to false.

Bou

'an

also

register

The DEverlasting "erviceD ;nti$Pattern


Fne anti-pattern that is all too pre!alent in An"roi" is the Ge!erlasting ser!i'eG. %u'h a ser!i'e is starte" !ia startService ! an" ne!er stops O the 'omponent starting it "oes not stop it an" it "oes not stop itsel& !ia stopSelf !. Why is this an anti-patternJ

8he ser!i'e takes up memory all o& the time. 8his is ba" in its oAn right i& the ser!i'e is not 'ontinuously "eli!ering su&&i'ient !alue to be Aorth the memory. $sers, &earing ser!i'es that sap their "e!i'e:s C#$ or AM, may atta'k the ser!i'e Aith so-'alle" Gtask killerG appli'ations or may terminate the ser!i'e !ia the %ettings app, thereby "e&eating your original goal. An"roi" itsel&, "ue to user &rustration Aith sloppy "e!elopers, Aill terminate ser!i'es it "eems ill-use", parti'ularly ones that ha!e run &or ?uite some time.

F''asionally, an e!erlasting ser!i'e is the right solution. 8ake a .F0# 'lient, &or e>ample. A .F0# 'lient usually nee"s to hol" an open so'ket Aith the .F0# ser!er to knoA about in'oming 'alls. 8he only Aay to 'ontinuously Aat'h &or in'oming 'alls is to 'ontinuously hol" open the so'ket. 8he only 'omponent 'apable o& "oing that Aoul" be a ser!i'e, so the ser!i'e Aoul" ha!e to 'ontinuously run. +oAe!er, in the 'ase o& a .F0# 'lient, or a musi' player, the user is the one spe'i&i'ally re?uesting the ser!i'e to run &ore!er. 1y using startJoreground !, a ser!i'e 'an ensure it Aill not be stoppe" "ue to ol" age &or 'ases like this.
08/
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

; vance

"ervice Patterns

http://commonsware.com/AdvAndroid

As a 'ounter-e>ample, imagine an email 'lient. 8he 'lient Aishes to 'he'k &or neA email messages perio"i'ally. 8he right solution &or this is the 6larm8anager pattern "es'ribe" earlier in this 'hapter. 8he anti-pattern Aoul" ha!e a ser!i'e running 'onstantly, spen"ing most o& its time Aaiting &or the polling perio" to elapse (e.g., !ia ?0read.sleep !). 8here is no !alue to the user in taking up AM to Aat'h the 'lo'k ti'k. %u'h ser!i'es shoul" be reAritten to use 6larm8anager. Most o& the time, though, it appears that ser!i'es are simply leake". 8hat is one a"!antage o& using 6larm8anager an" an IntentService O it is "i&&i'ult to leak the ser!i'e, 'ausing it to run in"e&initely. 0n &a't, IntentService in general is a great implementation to use Ahene!er you use the 'omman" pattern, as it ensures that the ser!i'e Aill shut "oAn e!entually. 0& you use a regular ser!i'e, be sure to shut it "oAn Ahen it is no longer a'ti!ely "eli!ering !alue to the user.

08'
Free excerpt from _The Busy Coder's Guide to Advanced Android Development_. Copyright (c) 2011 CommonsWare, LLC. All Rights Reserved

You might also like