廣播與服務(wù)

廣播接收者

  • BroadcastReceiver
  • 接收系統(tǒng)發(fā)出的廣播
  • 現(xiàn)實(shí)中的廣播:電臺(tái)為了傳達(dá)一些消息,而發(fā)送的廣播,通過廣播攜帶要傳遞的消息,群眾只要買了收音機(jī),就可以收到廣播了
  • Android中的廣播:系統(tǒng)在運(yùn)行過程中,會(huì)發(fā)生很多事件,系統(tǒng)為了讓其他應(yīng)用知道系統(tǒng)發(fā)生了這個(gè)事件,會(huì)發(fā)送一個(gè)對(duì)應(yīng)事件的廣播,比如:電量改變,收到短信,撥打電話,屏幕解鎖,系統(tǒng)開機(jī),只有注冊(cè)一個(gè)廣播接收者,就可以接收到系統(tǒng)發(fā)送的廣播。

IP撥號(hào)器

  • 系統(tǒng)撥打號(hào)碼時(shí),會(huì)發(fā)出一個(gè)廣播,廣播中會(huì)攜帶撥打的號(hào)碼,注冊(cè)廣播接收者接收這個(gè)廣播,取出這個(gè)號(hào)碼,修改號(hào)碼,然后把修改的號(hào)碼重新放入廣播。

  • 原理


    原理

定義方式

  • 定義一個(gè)類繼承BroadCastReceiver
  • 在清單文件中配置該類,并指定接收的廣播種類必須配置intent-filter。


    Paste_Image.png

    需要加入權(quán)限:

<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
  • 廣播是通過Intent發(fā)送的,Intent中會(huì)攜帶一個(gè)action,系統(tǒng)會(huì)在所有的清單文件中尋找,看哪個(gè)一個(gè)廣播接收器的intent-filter 和廣播中的intent是匹配的,那么這個(gè)廣播接收器就會(huì)收到這條廣播。
代碼
  • 廣播運(yùn)行在哪個(gè)進(jìn)程里面就看她運(yùn)行在哪個(gè)項(xiàng)目里面。
    如果關(guān)掉應(yīng)用進(jìn)程之后,廣播接收者還是會(huì)接收,即便沒有啟動(dòng)應(yīng)用進(jìn)程,廣播發(fā)出來時(shí),系統(tǒng)也會(huì)啟動(dòng)這個(gè)進(jìn)程,然后把廣播交給廣播接受者。
    廣播接受者所在進(jìn)程是不怕被殺掉的。

短信防火墻原理

短信防火墻
短信接收器

需要的權(quán)限:

<uses-permission android:name="android.permission.RECEIVE_SMS"/>
注冊(cè)接收器

可以取大于1000的數(shù),取整數(shù)的最大值

  • 一條短信是由很多 條短信拼接起來的,所以是數(shù)組形式
  • 短信攔截必須在有短信時(shí)就攔截就必須優(yōu)先級(jí)要高,系統(tǒng)短信優(yōu)先級(jí)不高于1000,先一步收到短信廣播,然后攔截廣播,短信應(yīng)用就收不到短信的。


    短信代碼
  • 4.0之后,用戶手動(dòng)開啟進(jìn)程,那么廣播接收者才能生效
  • 4.0之后,用戶手動(dòng)停止進(jìn)程,那么廣播接受者再也不會(huì)啟動(dòng)了,直到用戶下一次手動(dòng)啟動(dòng)進(jìn)程。

監(jiān)聽SD卡狀態(tài)

監(jiān)聽SD卡不需要權(quán)限

注冊(cè)監(jiān)聽器設(shè)置要監(jiān)聽的Action

監(jiān)聽SD卡

開機(jī)勒索軟件

注冊(cè)廣播接收器
加入權(quán)限

廣播接收器代碼
  • 在廣播接收器中啟動(dòng)Activity 出現(xiàn)錯(cuò)誤


    出現(xiàn)錯(cuò)誤
  • 啟動(dòng)一個(gè)新的任務(wù)棧來保存Activity,之前我們啟動(dòng)Activity是直接點(diǎn)擊圖標(biāo)啟動(dòng)的,啟動(dòng)Activity本身是有任務(wù)棧的,我們現(xiàn)在在一個(gè)Activity任務(wù)棧之外啟動(dòng)Activity就會(huì)出現(xiàn)問題。因?yàn)楫?dāng)前沒有任務(wù)棧。需要直接創(chuàng)建一個(gè)任務(wù)棧。
創(chuàng)建任務(wù)棧

應(yīng)用的安裝卸載和更新

  • 注冊(cè)廣播


    安裝卸載廣播
  • 廣播接收處理


    廣播代碼

發(fā)送自定義廣播

  • 發(fā)送廣播


    發(fā)送代碼

    *接收廣播


    接收代碼

有序和無序廣播

  • 無序廣播
    所有與廣播中的Intent匹配的廣播接收者,都可以收到這條廣播,并且不分先后順序,視為同時(shí)收到。

  • 有序廣播
    所有與廣播中的intent匹配的廣播接收者,都可以收到這條廣播,但是分先后順序,優(yōu)先級(jí)高的先收到,優(yōu)先級(jí)低的后收到。

發(fā)送有序廣播
設(shè)置結(jié)果接收器
設(shè)置接收者

設(shè)置接收者優(yōu)先級(jí)

服務(wù)

  • Service
    四大組件之一
    運(yùn)行于后臺(tái),沒有前臺(tái)界面,用于運(yùn)行需要在后臺(tái)運(yùn)行的代碼
    如:下載任務(wù),音樂播放。
    如果下載線程放在Activity中時(shí),
    按home和返回鍵 銷毀Activity之后 下載還可以運(yùn)行,這是因?yàn)榫€程還在進(jìn)程運(yùn)行,但是進(jìn)程被殺掉之后,線程就會(huì)被銷毀。當(dāng)內(nèi)存不足時(shí)就會(huì)殺掉進(jìn)程,因此不要把下載放在Activity中。

  • Empty 進(jìn)程(沒有任何活動(dòng)的應(yīng)用組件(Activity和Service))
    一個(gè)進(jìn)程不包含任何活躍的應(yīng)用組件(指的是服務(wù)和Activity),保持該類型進(jìn)程活躍的原因只是是緩存,提高下次組件在該進(jìn)程中的開啟速度。
    該進(jìn)程很容易被殺掉

  • 后臺(tái)進(jìn)程(如按home鍵)
    如果一個(gè)進(jìn)程持有一個(gè)對(duì)用戶不可見的Activity時(shí)(該activity的onStop()方法已經(jīng)被調(diào)用),這些進(jìn)程對(duì)用戶的體驗(yàn)沒有直接的影響。
    很容易被殺死

  • 服務(wù)進(jìn)程(相比bindService而言,這個(gè)才是真正用來下載,不到萬不得已不會(huì)被殺死)
    擁有一個(gè)服務(wù)的進(jìn)程。
    該進(jìn)程中正在運(yùn)行的是以startService()方法開啟的服務(wù)。

  • 可見進(jìn)程

  • 擁有一個(gè)不在前臺(tái)但對(duì)用戶依然可見的Activity(onPause()方法被調(diào)用)的進(jìn)程

  • 擁有一個(gè)與可見Activity(onPause()方法被調(diào)用)綁定的服務(wù)(特指遠(yuǎn)程服務(wù))

  • 前臺(tái)進(jìn)程

    • 擁有一個(gè)正在與用戶交互的Activity(onResume()方法調(diào)用)
    • 擁有一個(gè)與正在與用戶交互的Activity綁定的服務(wù)(特指遠(yuǎn)程服務(wù))
    • 擁有一個(gè)運(yùn)行在前臺(tái)的服務(wù)(服務(wù)調(diào)用了startForeground())
    • 擁有一個(gè)正在執(zhí)行其中一個(gè)生命周期方法( onCreate(),onStartCommand(),or onDestory())的服務(wù)。
      保證生命周期執(zhí)行完畢,短暫提高優(yōu)先級(jí),保證代碼執(zhí)行完畢,完成后就自動(dòng)降為服務(wù)進(jìn)程。在內(nèi)存不足不被殺掉。
    • 擁有一個(gè)正在執(zhí)行onReceive的方法的廣播接受者。執(zhí)行完畢該殺就被殺。

服務(wù)的啟動(dòng)和停止

  • 定義方式:創(chuàng)建java類再繼承Service類,清單文件做配置。
    可以理解為:沒有界面的Activity。


    啟動(dòng)服務(wù)
  • 服務(wù)單位生命周期
    startService的生命周期:
    onStartCommand:可以多次被調(diào)用
    onCreate:只會(huì)被調(diào)用一次
    onDestory:值會(huì)被調(diào)用
  • onCreate->onStartCommand->onDestory
    重復(fù)的startService不會(huì)調(diào)用onCreate只會(huì)重復(fù)調(diào)用onStartCommand

通話錄音機(jī)

  • 空閑
  • 響鈴
  • 摘機(jī)
    先監(jiān)聽電話狀態(tài)
    監(jiān)聽服務(wù)

    MediaRecorder使用方法
    開啟錄音機(jī)MediaRecorder
使用完MediaRecorder釋放資源為什么要release()

電話權(quán)限

服務(wù)的兩種啟動(dòng)方式及生命周期

startService

  • 通過startService啟動(dòng)的服務(wù),該服務(wù)所在的進(jìn)程會(huì)變成服務(wù)進(jìn)程。
  • Service 與啟動(dòng)它的Activity沒有關(guān)系。

bindService

  • 通過bindService啟動(dòng)的服務(wù),進(jìn)程優(yōu)先級(jí)不變。
  • 綁定出來的Service不是服務(wù)進(jìn)程,它的優(yōu)先級(jí)跟他本身綁定的Activit有關(guān),Activity 是后臺(tái)的,那就是后臺(tái)進(jìn)程,Activity沒有了,那就是空進(jìn)程。
    綁定出來的Service是不能作為后臺(tái)操作的。很容易死掉進(jìn)程。

不能再次解綁的,重復(fù)解綁會(huì)報(bào)錯(cuò)。
綁定服務(wù)后,直接按返回鍵會(huì)報(bào)錯(cuò)。說明綁定服務(wù)不能作為后臺(tái)操作

返回錯(cuò)誤
  • 綁定的服務(wù)于啟動(dòng)它的Activity是同生共死的,Activity銷毀了,服務(wù)也要銷毀。服務(wù)銷毀了,activity不銷毀。

調(diào)用服務(wù)中的方法

對(duì)比辦證服務(wù)

回調(diào)類ServiceConnection

服務(wù)連接回調(diào)

把中間人的方法抽取到接口中

抽取接口

實(shí)現(xiàn)抽取方法

強(qiáng)轉(zhuǎn)

為什么要這么做,不私有化方法呢?

模擬音樂播放器

混合啟動(dòng)Service(startService和bindService)

start->bind->unbind->stop
因?yàn)橐WC音樂播放器退出后音樂還在播放,就必須啟動(dòng)服務(wù)進(jìn)程

  • 一定要先啟動(dòng)后綁定
    先啟動(dòng)startService
    onCreate->onStartCommand
    再綁定
    ->onBind
    再解綁 服務(wù)還在
    ->onUnbind ( 不會(huì)被摧毀)
    再摧毀
    ->onDetory
  • 如果先bindService(邏輯會(huì)出問題)
    onCreate->onbind
    再startService
    ->onStartCommand
    再stopService
    ->服務(wù)什么也不干
    最后解綁
    ->onUnbind(會(huì)銷毀)

使用代碼注冊(cè)和反注冊(cè)廣播接受者

清單文件注冊(cè)

  • 廣播接收者永遠(yuǎn)生效,除非卸載應(yīng)用,或者手動(dòng)停止進(jìn)程(如防火墻)

代碼注冊(cè)

通常和service聯(lián)系在一起,一般啟動(dòng)服務(wù)來注冊(cè)。

  • 需要廣播接收者生效時(shí),注冊(cè)它,不需要時(shí),反注冊(cè)它,反注冊(cè)之后,廣播接收者就失效了。(只在需要時(shí)注冊(cè))

  • 特殊廣播接收者,必須代碼注冊(cè)。
    這種需求沒有必要一直生效。因?yàn)檫@些廣播變化得很快,次數(shù)很頻繁。
    (清單文件注冊(cè)了而沒有代碼注冊(cè)也接收不到)

    • 屏幕開關(guān)
    • 電量改變
  • 第一步定義服務(wù)并在清單文件中注冊(cè)服務(wù)

定義服務(wù)并在創(chuàng)建中注冊(cè)廣播在銷毀中注銷廣播
  • 第二步定義廣播接收器
定義廣播接收器
注冊(cè)和反注冊(cè)時(shí)需要注意的

啟動(dòng)和綁定遠(yuǎn)程服務(wù)

服務(wù)的分類

都是在手機(jī)上與web不一樣

本地服務(wù)

  • 與啟動(dòng)者都在同一應(yīng)用的服務(wù)

遠(yuǎn)程服務(wù)

  • 與啟動(dòng)者不在同一應(yīng)用的服務(wù)

本地服務(wù)使用顯示啟動(dòng)
遠(yuǎn)程服務(wù)使用隱式啟動(dòng)

注意:Android 5.0 之后 Service必須顯示啟動(dòng),不然會(huì)報(bào)錯(cuò)

Service隱式啟動(dòng)會(huì)報(bào)錯(cuò)

解決方案

解決方法

遠(yuǎn)程服務(wù)中使用aidl

進(jìn)程間通信

  • AIDL
    android interface definition language
    在Android中進(jìn)行進(jìn)程間通訊

步驟:

遠(yuǎn)程Service

1.把接口文件的后后綴名.aidl;(在gen中自動(dòng)生成.java文件)
2.aidl文件中的所有東西都是public ,不需要訪問修飾符;
3.中間人對(duì)象繼承Stub,這個(gè)抽象類Stub已經(jīng)繼承了Binder并實(shí)現(xiàn)了aidl里面的方法。


遠(yuǎn)程Service

訪問遠(yuǎn)程服務(wù)

1.把上述的aidl文件復(fù)制到訪問遠(yuǎn)程服務(wù)的工程中,然后aidl所在的包名必須和遠(yuǎn)程Service中的aidl一致。

2.把獲取的中間人對(duì)象使用Stub.asInterface強(qiáng)轉(zhuǎn)。

訪問遠(yuǎn)程Service

支付寶遠(yuǎn)程服務(wù)

不安全做法
安全做法

進(jìn)程優(yōu)先級(jí)的補(bǔ)充

確定取消對(duì)話框

設(shè)置對(duì)話框

單選對(duì)話框

setMessage 是絕對(duì)不能設(shè)置的,會(huì)將單選內(nèi)容蓋掉。

單選對(duì)話框

設(shè)置多選對(duì)話框

設(shè)置多選對(duì)話框

設(shè)置進(jìn)度條對(duì)話框

設(shè)置進(jìn)度條對(duì)話框

樣式和主題

  • 樣式和主題定義的方式是一模一樣的
  • 布局文件中使用樣式
  • 清單文件中使用主題


    樣式和主題的定義方式

國(guó)際化

國(guó)際化

圖片也能國(guó)際化:


圖片國(guó)際化
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 服務(wù)兩種啟動(dòng)方式(掌握) startService開始服務(wù),會(huì)使進(jìn)程變成為服務(wù)進(jìn)程啟動(dòng)服務(wù)的activity和服務(wù)...
    法神趙日天閱讀 468評(píng)論 0 0
  • 廣播(掌握) 廣播的概念現(xiàn)實(shí):電臺(tái)通過發(fā)送廣播發(fā)布消息,買個(gè)收音機(jī),就能收聽Android:系統(tǒng)在產(chǎn)生某個(gè)事件時(shí)發(fā)...
    法神趙日天閱讀 443評(píng)論 0 2
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,663評(píng)論 19 139
  • 本文出自 Eddy Wiki ,轉(zhuǎn)載請(qǐng)注明出處:http://eddy.wiki/interview-androi...
    eddy_wiki閱讀 3,380評(píng)論 0 20
  • 最近剛從舊公司離職,為面試在做準(zhǔn)備,因?yàn)槠綍r(shí)開發(fā)CV大法用得比較多,很多基礎(chǔ)知識(shí)掌握得不是很牢靠以及很多工具框架只...
    黎清海閱讀 2,331評(píng)論 1 19

友情鏈接更多精彩內(nèi)容