Android 服务入门
?
前言:硬著頭皮把數(shù)據(jù)庫(kù)SQLite看完了,接下來(lái)就是android服務(wù)了,因?yàn)樽约罕旧砭褪遣锁B(niǎo),所以呢,也只是做做筆記,技術(shù)上的東西就別指望我了。
?
1.什么是服務(wù)呢?舉個(gè)例子,百度地圖,美團(tuán)外賣,OFO,可以獲取你的位置,就提供了位置服務(wù),通知服務(wù)基本上每個(gè)APP都會(huì)有。再舉個(gè)例子,你開(kāi)啟一個(gè)網(wǎng)易云在后臺(tái)運(yùn)行,你希望切換到另外一個(gè)應(yīng)用依舊可以聽(tīng)到音樂(lè),這也是服務(wù)。
?
2.服務(wù)是沒(méi)有用戶界面的,它是背后默默為人民服務(wù)的。只要運(yùn)行了服務(wù),你就可以放手地去做其他事情了。
?
3.有兩種類型的服務(wù),-----Start services-----啟動(dòng)服務(wù)-----從互聯(lián)網(wǎng)下載一個(gè)大文件,-----Bound services-----綁定服務(wù)-----汽車?yán)锍瘫怼?/p>
?
4.先說(shuō)一下Start Services,代碼中用extends Service類或者extends IntentService類?創(chuàng)建一個(gè)服務(wù)。顧名思義,前者提供了基本的服務(wù)功能,后者還可以和意圖Intent掛鉤。新建服務(wù)時(shí),最好通過(guò)File-----New-----Service-----創(chuàng)建新的IntentService-----服務(wù)命名自定義。比如啊,創(chuàng)建一個(gè)IntentService,服務(wù)運(yùn)行在onHandleIntent這個(gè)方法中,是復(fù)寫的方法。
?
5.繼續(xù)IntentService,再建立一個(gè)活動(dòng),方便調(diào)用服務(wù)。主要業(yè)務(wù)邏輯都在onHandlerIntent中進(jìn)行,這里用了一個(gè)synchronized(this){wait(10000)}內(nèi)部方法,現(xiàn)學(xué)現(xiàn)賣一下,意思就是同步。這里wait(10000)和時(shí)間掛鉤了,等待10s,所以肯定不會(huì)那么簡(jiǎn)單,總之知道怎么用就行了。
?
6.服務(wù)要在AndroidManifest.xml進(jìn)行聲明。與Activity同一級(jí),<service android:name=.服務(wù)名 ?android:exported="false"></>?那exported是什么意思呢,就是告訴Android,這個(gè)服務(wù)可以有其他應(yīng)用使用,false表示這個(gè)服務(wù)只能在當(dāng)前應(yīng)用中使用。
?
7.活動(dòng)怎么調(diào)用服務(wù)呢,在主布局中增加一個(gè)按鈕,單擊按鈕調(diào)用活動(dòng)的onClick方法。在方法中?Intent intent=new Intent(this,服務(wù)名.class)-----intent.putExtra(字符串,意圖文本)-----startService(intent),是不是超像調(diào)用活動(dòng),也許啊,就是那些谷歌開(kāi)發(fā)人員懶得重新建一個(gè)服務(wù)的調(diào)用,就直接在原有的基礎(chǔ)上多寫一個(gè)構(gòu)造函數(shù)吧。
?
8.如何和主線程掛鉤呢,這里服務(wù)也為我們提供了一個(gè)方法,onStartCommand-----在每次啟動(dòng)意圖服務(wù)時(shí),都會(huì)調(diào)用這個(gè)方法,比onHandleIntent方法還要快。所以呢,在onStartCommand創(chuàng)建一個(gè)處理消息的Handler就可以向主線程傳遞消息了。昨天也寫了一篇博客,Handler必須要定義在主線程中,他就是主線程定義的一個(gè)使者,為了監(jiān)督子線程的工作情況的。
?
9.服務(wù)中的用一個(gè)Toast訪問(wèn)屏幕咋辦呢?有了handler之后就方便很多了,直接handler.post復(fù)寫一個(gè)run方法,再Toast就可以了?嗎?可是服務(wù)中的上下文是無(wú)法訪問(wèn)屏幕的,那咋辦呢?getApplicationContext()不就可以了嘛!
?
10.Toast個(gè)人感覺(jué)用戶體驗(yàn)并不是特別好,所以這里要多改進(jìn)改進(jìn),試著用別的方法來(lái)替換Toast()方法。就用通知吧,一般應(yīng)用都會(huì)有的,其實(shí)也很煩,但是也要學(xué)啊。-----主要方法就是,在服務(wù)中創(chuàng)建一個(gè)NotificationManager對(duì)象,用來(lái)訪問(wèn)Android的通知服務(wù)的。
?
11.怎么在服務(wù)中創(chuàng)建一個(gè)通知呢
Notification notification=new Notification.Builder(this).多個(gè)set.build()? 即可。set什么東西呢?比如啊,通知圖標(biāo),標(biāo)題,文本,聲音,通知個(gè)數(shù),優(yōu)先級(jí),如果不會(huì)-----就在goole或者baidu上搜索關(guān)鍵字-----使用通知生成器創(chuàng)建通知。
?
12.當(dāng)你點(diǎn)擊一個(gè)通知時(shí),你想跳到活動(dòng)中去咋辦呢?這就有點(diǎn)小復(fù)雜了。
(1)創(chuàng)建一個(gè)顯示意圖,就和之前活動(dòng)跳轉(zhuǎn)一樣。
(2)將這個(gè)意圖傳遞到TaskStackBuilder??-----它允許訪問(wèn)后退按鈕使用的活動(dòng)歷史-----就是保證活動(dòng)啟動(dòng)時(shí)后退按鈕可以正常工作而已-----不要想得太復(fù)雜了。
(3)從TaskStackBuilder得到掛起意圖??用? PendingIntent??接收stackBuilder對(duì)象的getPendingIntent()函數(shù)。里面有兩個(gè)參數(shù),一個(gè)是標(biāo)志,一個(gè)是掛起意圖的行為。
(4)向通知增加意圖??-----notification.setContentIntent(pendingIntent)?
(5)用通俗的話來(lái)講,就是-----掛起意圖被玩來(lái)玩去-----先從服務(wù)中創(chuàng)建-----在被TaskStackBuilder玩弄是非-----在從getPendingIntent中得到-----最后回到通知的懷抱。
?
13.回到通知的懷抱之后,就要發(fā)起總攻了,那就是Android的通知服務(wù)-----完成在設(shè)備上顯示的大業(yè)。首先要有一個(gè)旗號(hào),才能鼓舞更多的人,就是通知的ID-----其次直接getSystenService()來(lái)獲得訪問(wèn)權(quán)限-----通過(guò)這個(gè)“通知經(jīng)理”來(lái)創(chuàng)建通知。這樣,所有的通知基本上都通過(guò)這個(gè)經(jīng)理組織起來(lái)了。
?
14.簡(jiǎn)單講一下整個(gè)過(guò)程,首先呢,MainActivity通過(guò)一個(gè)意圖-----聯(lián)系到MessageService服務(wù)(類似于一個(gè)活動(dòng)一樣傳遞即可)-----執(zhí)行服務(wù)中的代碼,主要是修改onHandleIntent,顧名思義就是消息處理中心-----然后里面隨便寫一個(gè)方法-----方法實(shí)現(xiàn)了將普通意圖升級(jí)成掛起意圖-----掛起意圖升級(jí)為通知-----通知最后告訴Android先生。
?
15.然后就是綁定服務(wù)呢,一聽(tīng)這個(gè)名字,就是牢牢綁住用戶-----所以更具有交互性-----類似于汽車的里程表。它怎么工作呢?
?
16.主要有以下幾個(gè)步驟-----如監(jiān)聽(tīng)用戶行走路徑-----用到了位置服務(wù)
(1)定義一個(gè)OdometerBinder-----只要繼承Binder即可。利用這個(gè)對(duì)象可以把活動(dòng)連接到OdometerService ?。
(2)創(chuàng)建一個(gè)LocationListener,向Android的位置服務(wù)注冊(cè)這個(gè)監(jiān)聽(tīng)器-----計(jì)算已經(jīng)走過(guò)的里程數(shù)
(3)創(chuàng)建一個(gè)公共getMiles()方法-----活動(dòng)可以使用這個(gè)方法得到走過(guò)的里程數(shù)。
?
17.怎么綁定呢?主活動(dòng)創(chuàng)建一個(gè)ServiceConnection對(duì)象-----活動(dòng)通過(guò)這個(gè)連接將一個(gè)意圖傳遞到服務(wù)-----綁定服務(wù)創(chuàng)建一個(gè)Binder對(duì)象-----服務(wù)通過(guò)連接發(fā)回Binder-----活動(dòng)接收到Binder對(duì)象后,取出Service對(duì)象,使用這個(gè)服務(wù)。
?
18.用通俗的話講,就是ServiceConnection作為一個(gè)中介代理,左邊是MainActivity,右邊是Service,總之,ServiceConnection就像一座橋一樣,連通了這條路,缺一不可。
?
19.在這條路中來(lái)回穿梭的車子,就是Binder了。活動(dòng)使用OdometerBinder類部類來(lái)獲得OdometerService的一個(gè)引用。
?
20.Service類提供了4大天王,onCreate是創(chuàng)建服務(wù),onStartCommand是第一次啟動(dòng),onBind是綁定到服務(wù),onDestroy是撤銷服務(wù)。
?
21.所以說(shuō),如何得到設(shè)備的位置呢?just a LocationListener-----它有four個(gè)override-----onLocationChanged-----onProviderDisabled-----onProviderEnabled-----onStatusChanged
?
22.然后是注冊(cè)監(jiān)聽(tīng)器,基本使用這些高檔的方法,都要問(wèn)一下Android君,我可以用一下位置服務(wù)嗎?安卓君派一個(gè)經(jīng)理-----這里是LocationManager-----幫助他完成大業(yè)。
?
23.經(jīng)理是可以輕松得到信息的,活動(dòng)不知道啊,那怎么辦呢?創(chuàng)建一個(gè)方法來(lái)訪問(wèn)服務(wù)嘛-----可以提供更加精準(zhǔn)的人性化的數(shù)據(jù),如提供幾千米,幾英里-----國(guó)人一般用千米。
?
24.簡(jiǎn)單總結(jié)一下,首先是一個(gè)自定義服務(wù)繼承Service-----里面有一個(gè)自定義Binder繼承Binder-----復(fù)寫一個(gè)onBind將活動(dòng)綁定到服務(wù)-----復(fù)寫一個(gè)onCreate方法用來(lái)創(chuàng)建服務(wù)是建立位置監(jiān)聽(tīng)器-----onCreate里面的監(jiān)聽(tīng)器有4個(gè)方法要復(fù)寫-----最重要的是onLocationChanged-----onCreate最后要向位置Android君請(qǐng)求,之后向位置服務(wù)注冊(cè)位置監(jiān)聽(tīng)器-----最后自定義一個(gè)方法在活動(dòng)中得到數(shù)據(jù),如轉(zhuǎn)換公里數(shù)。
?
25.這里涉及到了GPS,安卓君對(duì)這個(gè)東西管理得比較嚴(yán)格,所以在AndroidManifest.xml中要聲明一下權(quán)限-----否則會(huì)崩潰噠。其次服務(wù)也要聲明,任何服務(wù)都要聲明,每個(gè)服務(wù)都會(huì)有一個(gè)名字,android:exported-----只有這個(gè)應(yīng)用才使用這個(gè)服務(wù),android:enabled-----應(yīng)用能否使用這個(gè)服務(wù)。
?
26.緊接著就是用測(cè)試了,用一個(gè)Main活動(dòng)來(lái)處理。將她綁定到服務(wù)-----更新文本視圖。
?
27.怎么綁定呢?just a ServiceConnection-----它有兩個(gè)方法-----onServiceConnected用來(lái)建立與服務(wù)的連接-----onServiceConnected用來(lái)失去服務(wù)連接。
?
28.Main中的私有成員,我稱私有成員為-----僅僅是從別人那里得到暫用一下-----別人那得到是將別的東西賦給它-----暫用一下是得到之后肯定要用什么方法。
?
29.Main活動(dòng)啟動(dòng)時(shí)要綁定到服務(wù),怎么綁定呢?just?in?onStart---復(fù)寫Main中的onStart方法-----創(chuàng)建一個(gè)顯示意圖,指定你要綁定的服務(wù)-----然后活動(dòng)提供了一個(gè)重要的方法-----bindService來(lái)將意圖和連接掛鉤。
?
30.有了onStart方法,當(dāng)然不能少了onStop方法了,just?啊unbindService方法來(lái)解除服務(wù)綁定。
?
31.然后就是布局要顯示什么東西了。注意要用到視圖更新,就要用到handler來(lái)處理,handler可以分兩部分,也可以簡(jiǎn)寫,前面我也寫了一篇博客-----線程+handler+Thread,這里提供了一個(gè)更加簡(jiǎn)單的方法,handler.post(new Runnable(){.....}),我在想這個(gè)創(chuàng)造這個(gè)函數(shù)的人是不是太懶了,感覺(jué)只適合牛人用。
?
32.整理一下思路,首先在Main中建立兩個(gè)私有成員-----自定義服務(wù)類-----boolean是否綁定到服務(wù)。然后是定義一個(gè)ServiceConnection-----用來(lái)連接服務(wù)時(shí)得到一個(gè)自定義服務(wù)的引用-----復(fù)寫了onServiceConnected-----復(fù)寫了onServiceDisConnected??。然后是一個(gè)onCreate函數(shù)-----里面加載布局和視圖更新的函數(shù)。??然后是復(fù)寫onStart方法-----驅(qū)動(dòng)活動(dòng)是綁定服務(wù)-----用了一個(gè)bindService方法(活動(dòng)本身有的)。??然后是復(fù)寫onStop方法-----活動(dòng)停止是解除服務(wù)綁定。?注意點(diǎn)就是視圖更新的函數(shù)用了handler來(lái)處理。
?
33.整個(gè)服務(wù)就看的差不多了,目的很簡(jiǎn)單,就只知道整個(gè)流程,用的時(shí)候會(huì)用-----現(xiàn)在時(shí)間緊迫,不求精通-----以后有空再深入研究一下。
?
早安!2017/7/11 7:50
轉(zhuǎn)載于:https://www.cnblogs.com/Jason-Jan/p/7144072.html
總結(jié)
以上是生活随笔為你收集整理的Android 服务入门的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 定时调度框架:Quartz.net
- 下一篇: 解决Android SDK更新慢