android四大組件的運行狀態

android四大組件:Activity,Service,BroadcastReceiver和ContentProvider.

一、異同點

android的四大組件組件中,除了BroadcastReceiver以外,其他的三種都必須在Android-Manifest中注冊,對于BroadcastReceiver來說,他可以在Android-Manifest中注冊,也可以通過代碼來注冊。在調用方式上,Activity,Service,和、BroadcastReceiver需要借助Intent,而ContentProvider不需要。

二、Activity的相關介紹

Activity是一種展示組件,用于向用戶直接的展示一個界面,并且可以接收用戶輸入的信息來進行交互。

1、什么是Activity?

Activity是一個負責與用戶交互的組件,Activity中所有操作都與用戶密切相關,可以通過setContentView(View)來顯示指定控件。

在一個android應用中,一個Activity通常就是一個單獨的屏幕,它上面可以顯示一些控件也可以監聽并處理用戶的事件做出響應。

2、請描述一下Activity生命周期。

onCreate(Bundle savedInstanceState):

創建activity時調用。設置在該方法中,還以Bundle的形式提供對以前儲存的任何狀態的訪問!

onStart():

activity變為在屏幕上對用戶可見時調用。

onResume():

activity開始與用戶交互時調用(無論是啟動還是重新啟動一個活動,該方法

總是被調用的)。

onPause():

activity被暫停或收回cpu和其他資源時調用,該方法用于保存活動狀態的,也

是保護現場,壓棧吧!

onStop():

activity被停止并轉為不可見階段及后續的生命周期事件時調用。

onRestart():

重新啟動activity時調用。該活動仍在棧中,而不是啟動新的活動。

onDestroy():

activity被完全從系統內存中移除時調用,該方法被調用

3、如何退出Activity?如何安全退出已調用多個Activity的Application?

在Android中退出程序比較麻煩,尤其是在多個Activity的程序中,在2.2之前可以采用如下代碼退出程序:

1.?ActivityManager am = (ActivityManager)getSystemService (Context.ACTIVITY_SERVICE);

2.?am.restartPackage(getPackageName());

此種方法是一種最方便和最簡單的退出程序的辦法,但是在2.2和2.2之后就不能用了,一種常用的方法是自定義一個Activity的棧,在程序退出時將棧中的所有的Activity進行finish。

還有一些其他的方式,在這http://alex-yang-xiansoftware-com.iteye.com/blog/1099207可查看。

4、如果后臺的Activity由于某原因被系統回收了,如何在被系統回收之前保存當前狀態?

答:重寫onSaveInstanceState()方法,在此方法中保存需要保存的數據,該方法將會在activity被回收之前調用。通過重寫onRestoreInstanceState()方法可以從中提取保存好的數據

5、?activity在屏幕旋轉時的生命周期

答:不設置Activity的android:configChanges時,切屏會重新調用各個生命周期,切橫屏時會執行一次,切豎屏時會執行兩次;設置Activity的android:configChanges="orientation"時,切屏還是會重新調用各個生命周期,切橫、豎屏時只會執行一次;設置Activity的android:configChanges="orientation|keyboardHidden"時,切屏不會重新調用各個生命周期,只會執行onConfigurationChanged方法。

6、?activity的啟動模式有哪些?是什么含義?

答:在android里,有4種activity的啟動模式,分別為:

“standard” (默認)

“singleTop”

“singleTask”

“singleInstance”

當應用運行起來后就會開啟一條線程,線程中會運行一個任務棧,當Activity實例創建后就會放入任務棧中。Activity啟動模式的設置在AndroidManifest.xml文件中,通過配置Activity的屬性android:launchMode=""設置。

1. Standared模式(默認)

我們平時直接創建的Activity都是這種模式的Activity,這種模式的Activity的特點是:只要你創建了Activity實例,一旦激活該Activity,則會向任務棧中加入新創建的實例,退出Activity則會在任務棧中銷毀該實例。

2. SingleTop模式

這種模式會考慮當前要激活的Activity實例在任務棧中是否正處于棧頂,如果處于棧頂則無需重新創建新的實例,會重用已存在的實例,否則會在任務棧中創建新的實例。

3. SingleTask模式

如果任務棧中存在該模式的Activity實例,則把棧中該實例以上的Activity實例全部移除,調用該實例的newInstance()方法重用該Activity,使該實例處於棧頂位置,否則就重新創建一個新的Activity實例。

4. SingleInstance模式

當該模式Activity實例在任務棧中創建后,只要該實例還在任務棧中,即只要激活的是該類型的Activity,都會通過調用實例的newInstance()方法重用該Activity,此時使用的都是同一個Activity實例,它都會處于任務棧的棧頂。此模式一般用于加載較慢的,比較耗性能且不需要每次都重新創建的Activity。

7、跟activity和Task 有關的 Intent啟動方式有哪些?其含義?核心的Intent Flag有:

FLAG_ACTIVITY_NEW_TASK

FLAG_ACTIVITY_CLEAR_TOP

FLAG_ACTIVITY_SINGLE_TOP

FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

FLAG_ACTIVITY_NEW_TASK

如果設置,這個Activity會成為歷史stack中一個新Task的開始。一個Task(從啟動它的Activity到下一個Task中的Activity)定義了用戶可以遷移的Activity原子組。Task可以移動到前臺和后臺;在某個特定Task中的所有Activity總是保持相同的次序。這個標志一般用于呈現“啟動”類型的行為:它們提供用戶一系列可以單獨完成的事情,與啟動它們的Activity完全無關。

FLAG_ACTIVITY_CLEAR_TOP

如果設置,并且這個Activity已經在當前的Task中運行,因此,不再是重新啟動一個這個Activity的實例,而是在這個Activity上方的所有Activity都將關閉,然后這個Intent會作為一個新的Intent投遞到老的Activity(現在位于頂端)中。

FLAG_ACTIVITY_SINGLE_TOP

如果設置,并且這個Activity已經在當前的Task中運行,因此,不再是重新啟動一個這個Activity的實例,而是在這個Activity上方的所有Activity都將關閉,然后這個Intent會作為一個新的Intent投遞到老的Activity(現在位于頂端)中。

FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

如果設置這個標志,這個activity不管是從一個新的棧啟動還是從已有棧推到棧頂,它都將以the front door of the task的方式啟動。這就講導致任何與應用相關的棧都講重置到正常狀態(不管是正在講activity移入還是移除),如果需要,或者直接重置該棧為初始狀態。

三、Service

Service是一種計算型組件,用于在后臺執行一系列的計算任務。由于在后臺,所以用戶無法直接感知到他的存在。Service和activity組件略有不同,activity組件只有一種運行模式,即activity處于啟動狀態,而Service卻有兩種狀態:啟動和綁定狀態。

1、android 關于service生命周期的onCreate()和onStart()說法正確的是(ad)(多選題)

A、當第一次啟動的時候先后調用onCreate()和onStart()方法

B、當第一次啟動的時候只會調用onCreate()方法

C、如果service已經啟動,將先后調用onCreate()和onStart()方法

D、如果service已經啟動,只會執行onStart()方法,不在執行onCreate()方法

2、Service是如何啟動

A. 通過startService;Service會經歷onCreate->onStart;stopService的時候直接onDestroy;如果是調用者(TestServiceHolder)自己直接退出而沒有調用stopService的話,Service會一直在后臺運行,下次TestServiceHolder再起來可以stopService。

B. 通過bindService;Service只會運行onCreate,這個時候TestServiceHolder和TestService綁定在一起,TestServiceHolder退出了,Srevice就會調onUnbind->onDestroyed,所謂綁定在一起就共存亡了。

3、Service用在哪個線程

默認情況下Service是運行在啟動該Service的應用主線程的,如果Service中的操作占用大量的CPU資源或有阻斷操作(比如播放MP3或者訪問網絡)會影響應用主線程的響應性能,甚至會造成“應用程序無響應(ANR)”問題。

4、簡單介紹服務

服務是沒有界面的長生命周期的代碼。一個很好的例子是媒體播放器從列表中播放歌曲。在一個媒體播放器程序中,大概要有一個或多個活動(activity)來供用戶選擇歌曲并播放它。然而,音樂的回放就不能使用活動(activity)了,因為用戶希望他導航到其他界面時音樂繼續播放。這種情況下,媒體播放器活動(activity)要用Context.startService()啟動一個服務來在后臺運行保持音樂的播放。系統將保持這個音樂回放服務的運行直到它結束。注意一下,你要用Context.bindService()方法連接服務(如果它沒有運行,要先啟動它)。當連接到服務后,你可以通過服務暴露的一個接口和它通信。對于音樂服務,它允許你暫停、倒帶,等等。

5、service和Thread區別?

1).Thread:Thread 是程序執行的最小單元,它是分配CPU的基本單位。可以用 Thread 來執行一些異步的操作。

2).Service:Service 是android的一種機制,當它運行的時候如果是Local Service,那么對應的 Service 是運行在主進程的 main 線程上的。如:onCreate,onStart 這些函數在被系統調用的時候都是在主進程的 main 線程上運行的。如果是Remote Service,那么對應的 Service 則是運行在獨立進程的 main 線程上。

四、BroadcastReceiver

BroadcastReceiver是一種消息型組件,用于在不同的組件中和不同的應用之間傳遞消息。同樣無法被用戶指甲感知到,因為他工作在系統內部。

在Android中,Broadcast是一種廣泛運用的在應用程序之間傳輸信息的機制。

1、用途:

實現了不同的程序之間的數據傳輸與共享,因為只要是和發送廣播的action相同的接受者都能接受這個廣播。典型的應用就是android自帶的短信,電話等等廣播,只要我們實現了他們的action的廣播,那么我們就能接收他們的數據了,以便做出一些處理。比如說攔截系統短信,攔截騷擾電話等

起到了一個通知的作用,比如在service中要通知主程序,更新主程序的UI等

因為service是沒有界面的,所以不能直接獲得主程序中的控件,這樣我們就只能在主程序中實現一個廣播接受者專門用來接受service發過來的數據和通知了

2、使用場景:

同一app內部的同一組件內的消息通信(單個或多個線程之間);

同一app內部的不同組件之間的消息通信(單個進程);

同一app具有多個進程的不同組件之間的消息通信;

不同app之間的組件之間消息通信;

Android系統在特定情況下與App之間的消息通信。

3、實現原理:

從實現原理看上,Android中的廣播使用了觀察者模式,基于消息的發布/訂閱事件模型。因此,從實現的角度來看,Android中的廣播將廣播的發送者和接受者極大程度上解耦,使得系統能夠方便集成,更易擴展。具體實現流程要點粗略概括如下:

廣播接收者BroadcastReceiver通過Binder機制向AMS(Activity Manager Service)進行注冊;

廣播發送者通過binder機制向AMS發送廣播;

AMS查找符合相應條件(IntentFilter/Permission等)的BroadcastReceiver,將廣播發送到BroadcastReceiver(一般情況下是Activity)相應的消息循環隊列中;

消息循環執行拿到此廣播,回調BroadcastReceiver中的onReceive()方法。

4、注冊方式

有倆種注冊方式分別是靜態注冊和動態注冊

靜態注冊

在AndroidManifest.xml 中:? ? . . .android:exported —— 此broadcastReceiver能否接收其他App的發出的廣播(其默認值是由receiver中有無intent-filter決定的,如果有intent-filter,默認值為true,否則為false。)android:name? —— 此broadcastReceiver類名;android:permission? ——如果設置,具有相應權限的廣播發送方發送的廣播才能被此broadcastReceiver所接收;android:process? ——broadcastReceiver運行所處的進程。默認為app的進程。可以指定獨立的進程(Android四大基本組件都可以通過此屬性指定自己的獨立進程)

動態注冊

無須在AndroidManifest中注冊組件。直接在代碼中通過調用Context的registerReceiver函數,可以在程序中動態注冊BroadcastReceiver。registerReceiver的定義形式如下:

registerReceiver(BroadcastReceiverreceiver,IntentFilterfilter)或:registerReceiver(BroadcastReceiverreceiver,IntentFilterfilter,StringbroadcastPermission,Handlerscheduler)

5、倆種注冊方式的區別

靜態注冊即使app退出,任然能接收到廣播

動態注冊時,當activity退出,就接收不到廣播了

但是 靜態注冊即使app退出,任然能接收到廣播 這種說法自Android 3.1開始有可能不再成立。

Android 3.1開始系統在Intent與廣播相關的flag增加了參數:

A. FLAG_INCLUDE_STOPPED_PACKAGES:包含已經停止的包(停止:即包所在的進程已經退出)

B. FLAG_EXCLUDE_STOPPED_PACKAGES:不包含已經停止的包

自Android3.1開始,系統本身則增加了對所有app當前是否處于運行狀態的跟蹤。在發送廣播時,不管是什么廣播類型,系統默認直接增加了值為FLAG_EXCLUDE_STOPPED_PACKAGES的flag,導致即使是靜態注冊的廣播接收器,對于其所在進程已經退出的app,同樣無法接收到廣播。

由此,對于系統廣播,由于是系統內部直接發出,無法更改此intent flag值,因此,3.1開始對于靜態注冊的接收系統廣播的BroadcastReceiver,如果App進程已經退出,將不能接收到廣播。

但是對于自定義的廣播,可以通過復寫此flag為FLAG_INCLUDE_STOPPED_PACKAGES,使得靜態注冊的BroadcastReceiver,即使所在App進程已經退出,也能能接收到廣播,并會啟動應用進程,但此時的BroadcastReceiver是重新新建的。

Intent intent = new Intent();

intent.setAction(BROADCAST_ACTION);

intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);

intent.putExtra("name", "qqyumidi");

sendBroadcast(intent);

替代方案: 通過將Service與App本身設置成不同的進程已經成為實現此類需求的可行替代方案。

6、其他

有序廣播

有序廣播的有序廣播中的“有序”是針對廣播接收者而言的,指的是發送出去的廣播被BroadcastReceiver按照先后循序接收。有序廣播的定義過程與普通廣播無異,只是其的主要發送方式變為:sendOrderedBroadcast(intent, receiverPermission, ...)。

對于有序廣播,其主要特點總結如下:

1>多個具當前已經注冊且有效的BroadcastReceiver接收有序廣播時,是按照先后順序接收的,先后順序判定標準遵循為:將當前系統中所有有效的動態注冊和靜態注冊的BroadcastReceiver按照priority屬性值從大到小排序,對于具有相同的priority的動態廣播和靜態廣播,動態廣播會排在前面。

2>先接收的BroadcastReceiver可以對此有序廣播進行截斷,使后面的BroadcastReceiver不再接收到此廣播,也可以對廣播進行修改,使后面的BroadcastReceiver接收到廣播后解析得到錯誤的參數值。當然,一般情況下,不建議對有序廣播進行此類操作,尤其是針對系統中的有序廣播。

應用內廣播

Android中的廣播可以跨進程甚至跨App直接通信,且注冊是exported對于有intent-filter的情況下默認值是true,所以安全隱患如下:

其他App可能會針對性的發出與當前App intent-filter相匹配的廣播,由此導致當前App不斷接收到廣播并處理;

其他App可以注冊與當前App一致的intent-filter用于接收廣播,獲取廣播具體信息。

7、增加安全性的方案:

對于同一App內部發送和接收廣播,將exported屬性人為設置成false,使得非本App內部發出的此廣播不被接收;

在廣播發送和接收時,都增加上相應的permission,用于權限驗證;

發送廣播時,指定特定廣播接收器所在的包名,具體是通過intent.setPackage(packageName)指定在,這樣此廣播將只會發送到此包中的App內與之相匹配的有效廣播接收器中。

相比于全局廣播,App應用內廣播優勢體現在:

安全性更高;

8、Android引入廣播機制的用意?

答:

a : 從MVC的角度考慮(應用程序內) ,其實回答這個問題的時候還可以這樣問,android為什么要有那4大組件,現在的移動開發模型基本上也是照搬的web那一套MVC架構,只不過是改了點嫁妝而已。android的四大組件本質上就是為了實現移動或者說嵌入式設備上的MVC架構,它們之間有時候是一種相互依存的關系,有時候又是一種補充關系,引入廣播機制可以方便幾大組件的信息和數據交互。

b:程序間互通消息(例如在自己的應用程序內監聽系統來電)

c:效率上(參考UDP的廣播協議在局域網的方便性)

d:設計模式上(反轉控制的一種應用,類似監聽者模式)


五、ContentProvider

ContentProvider是一種數據共享組件,用于向其他組件和其他應用共享數據。同樣無法直接被用戶感知。

1、ContentProvider的URI的配置?

清單文件之指定URI或者代碼里面指定URI,contentProvider通過URI訪問數據

2、contentprovider怎么實現數據共享?

一個程序可以通過實現一個Content provider的抽象接口將自己的數據完全暴露出去,而且Content providers是以類似數據庫中表的方式將數據暴露。Content providers存儲和檢索數據,通過它可以讓所有的應用程序訪問到,這也是應用程序之間唯一共享數據的方法。要想使應用程序的數據公開化,可通過2種方法:創建一個屬于你自己的Content provider或者將你的數據添加到一個已經存在的Content provider中,前提是有相同數據類型并且有寫入Content provider的權限。

3、如何通過一套標準及統一的接口獲取其他應用程序暴露的數據?

Android提供了ContentResolver,外界的程序可以通過ContentResolver接口訪問ContentProvider提供的數據。

4、ContentProvider和SQL的區別

Sql只能在該工程的內部共享數據,ContentProvider能在工程之間實現數據共享。

5、Android如何訪問自定義ContentProvider

第一:得到ContentResolver類對象:ContentResolver cr = getContentResolver();

第二:定義要查詢的字段String數組。

第三:使用cr.query();返回一個Cursor對象。

第四:使用while循環得到Cursor里面的內容


補充:

1、Intent的原理

intent是連接Activity, Service, BroadcastReceiver, ContentProvider四大組件的信使,,可以傳遞八種基本數據類型以及string, Bundle類型,以及實現了Serializable或者Parcelable的類型。

2、Intent可以劃分成顯式意圖和隱式意圖:

顯式意圖:調用Intent.setComponent()或Intent.setClass()方法明確指定了組件名的Intent為顯式意圖,顯式意圖明確指定了Intent應該傳遞給哪個組件。

隱式意圖:沒有明確指定組件名的Intent為隱式意圖。 Android系統會根據隱式意圖中設置的動作(action)、類別(category)、數據(URI和數據類型)找到最合適的組件來處理這個意圖。

3、IntentService有何優點?

Acitivity的進程,當處理Intent的時候,會產生一個對應的Service

Android的進程處理器現在會盡可能的不kill掉你

非常容易使用。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,156評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,401評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,069評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,873評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,635評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,128評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,203評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,365評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,881評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,733評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,935評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,475評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,172評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,582評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,821評論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,595評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,908評論 2 372

推薦閱讀更多精彩內容