2.1 Activity
1.Activity是什麼?
Activity是Android的四大組件之一。是用戶操做的可視化界面;它爲用戶提供了一個完成操做指令的窗口。
當咱們建立完畢Activity以後,須要調用setContentView()方法來完成界面的顯示;以此來爲用戶提供交互的入口。html
2.典型狀況下的Activity生命週期?
Activity啓動–>onCreate()–>onStart()–>onResume()
點擊home鍵回到桌面–>onPause()–>onStop()
再次回到原Activity時–>onRestart()–>onStart()–>onResume()
退出當前Activity時–>onPause()–>onStop()–>onDestroy()android
3.異常狀況下的Activity的生命週期 & 數據如何保存和恢復?
在onStop以前調用onSaveInstanceState保存當前Activity狀態,當Activity被從新建立後,系統調用
onRestoreInstanceState,而且把Activity銷燬時onSaveInstanceState方法所保存的Bundle對象
做爲參數傳遞給onRestoreInstanceState和onCreate方法
onRestoreInstanceState的調用時機發生在onStart以後數據庫
4.從Activity A跳轉到Activity B以後,而後再點擊back鍵以後,它們的生命週期調用流程是什麼?
從Activity A跳轉到Activity B
Activity A -> onPause()
Activity B -> onCreate()
Activity B -> onStart()
Activity B -> onResume()
Activity A -> onStop()數組
點擊back鍵
Activity B -> onPause()
Activity A -> onRestart()
Activity A -> onStart()
Activity A -> onResume()
Activity B -> onStop()
Activity B -> onDestroy()瀏覽器
5.如何統計Activity的工做時間?
Activity開始工做的起點是onResume()而工做的中止點爲onPause(),
所以當每次Activity調用onResume()的時候記錄一個時間a,每次調用onPause()的時候再記錄一個時間b,
那麼由b-a可得當次Activity工做的時間。安全
6.給我說說Activity的啓動模式 & 使用場景。
系統默認的啓動模式:standard
系統的默認模式,每次啓動一個Activity都會從新建立一個新的實例
棧頂複用模式:singleTop
若是在任務的棧頂正好存在該Activity的實例,就重用該實例( 會調用實例的 onNewIntent() ),
不然就會建立新的實例並放入棧頂,即便棧中已經存在該Activity的實例,只要不在棧頂,都會建立新的實例。
使用場景如新聞類或者閱讀類App的內容頁面。
棧內複用模式:singleTask
若是在棧中已經有該Activity的實例,就重用該實例(會調用實例的 onNewIntent() )。
重用時,會讓該實例回到棧頂,所以在它上面的實例將會被移出棧。若是棧中不存在該實例,將會建立新的實例放入棧中。
使用場景如瀏覽器的主界面。無論從多少個應用啓動瀏覽器,只會啓動主界面一次,其他狀況都會走onNewIntent,
而且會清空主界面上面的其餘頁面。
單實例模式:singleInstance
在一個新棧中建立該Activity的實例,並讓多個應用共享該棧中的該Activity實例。
一旦該模式的Activity實例已經存在於某個棧中,任何應用再激活該Activity時都會重用該棧中的實例
( 會調用實例的 onNewIntent() )。其效果至關於多個應用共享一個應用,無論誰激活該 Activity 都會進入同一個應用中。
使用場景如鬧鈴提醒,將鬧鈴提醒與鬧鈴設置分離。singleInstance不要用於中間頁面,若是用於中間頁面,跳轉會有問題,
好比:A -> B (singleInstance) -> C,徹底退出後,在此啓動,首先打開的是B。多線程
7.如何在任意位置關掉應用全部Activity & 如何在任意位置關掉指定的Activity?
封裝一個類,成員變量有一個List集合,當Activity執行onCreate()方法時將當前的Activity實例加入,
遍歷這個List且逐一調用finish()便可
給每一個啓動的Activity一個tag,根據這個tag和集合可達到在任意位置關閉指定Activity的效果。併發
8.Activity的啓動流程(從源碼角度解析)?
app啓動的過程有兩種狀況,第一種是從桌面launcher上點擊相應的應用圖標,
第二種是在activity中經過調用startActivity來啓動一個新的activity。
咱們建立一個新的項目,默認的根activity都是MainActivity,而全部的activity都是保存在堆棧中的,
咱們啓動一個新的activity就會放在上一個activity上面,而咱們從桌面點擊應用圖標的時候,因爲launcher自己也是一個應用,
當咱們點擊圖標的時候,系統就會調用startActivitySately(),通常狀況下,咱們所啓動的activity的相關信息都會保存在intent中,
好比action,category等等。咱們在安裝這個應用的時候,系統也會啓動一個PackaManagerService的管理服務,
這個管理服務會對AndroidManifest.xml文件進行解析,從而獲得應用程序中的相關信息,好比service,activity,Broadcast等等,而後得到相關組件的信息。
當咱們點擊應用圖標的時候,就會調用startActivitySately()方法,而這個方法內部則是調用startActivty(),
而startActivity()方法最終仍是會調用startActivityForResult()這個方法。
由於startActivityForResult()方法是有返回結果的,因此係統就直接給一個-1,就表示不須要結果返回了。
而startActivityForResult()這個方法實際是經過Instrumentation類中的execStartActivity()方法來啓動activity,
Instrumentation這個類主要做用就是監控程序和系統之間的交互。而在這個execStartActivity()方法中會獲取ActivityManagerService的代理對象,
經過這個代理對象進行啓動activity。啓動會就會調用一個checkStartActivityResult()方法,若是說沒有在配置清單中配置有這個組件,就會在這個方法中拋出異常了。
固然最後是調用的是Application.scheduleLaunchActivity()進行啓動activity,而這個方法中經過獲取獲得一個ActivityClientRecord對象,
而這個ActivityClientRecord經過handler來進行消息的發送,系統內部會將每個activity組件使用ActivityClientRecord對象來進行描述,
而ActivityClientRecord對象中保存有一個LoaderApk對象,經過這個對象調用handleLaunchActivity來啓動activity組件,
而頁面的生命週期方法也就是在這個方法中進行調用。app
9.啓動一個其它應用的Activity的生命週期分析。
同4異步
10.Activity任務棧是什麼?在項目中有用到它嗎?說給我聽聽
-android任務棧又稱爲Task,它是一個棧結構,具備後進先出的特性,用於存放咱們的Activity組件。
-咱們每次打開一個新的Activity或者退出當前Activity都會在一個稱爲任務棧的結構中添加或者減小一個Activity組件,所以一個任務棧包含了一個activity的集合, android系統能夠經過Task有序地管理每一個activity,並決定哪一個Activity與用戶進行交互:只有在任務棧棧頂的activity才能夠跟用戶進行交互。
-在咱們退出應用程序時,必須把全部的任務棧中全部的activity清除出棧時,任務棧纔會被銷燬。固然任務棧也能夠移動到後臺, 而且保留了每個activity的狀態. 能夠有序的給用戶列出它們的任務, 同時也不會丟失Activity的狀態信息。
-須要注意的是,一個App中可能不止一個任務棧,某些特殊狀況下,單獨一個Actvity能夠獨享一個任務棧。還有一點就是一個Task中的Actvity能夠來自不一樣的App,同一個App的Activity也可能不在一個Task中。
11.什麼狀況下Activity不走onDestory?
當 Activity 被另一個 Activity 覆蓋、失去焦點並不可見時處於 Stoped 狀態。
9.0的時候若是強行終止activity,那麼也不會執行onDestory
12.什麼狀況下Activity會單獨執行onPause?
同11
13.a->b->c界面,其中b是SingleInstance的,那麼c界面點back返回a界面,爲何?
SingleInstance 這是一種增強的singleTask模式,它除了具備singleTask模式全部的特性外,還增強了一點,那就是具備此種模式的Activity只能單獨位於一個任務棧中,換句話說,好比Activity A是singleInstance模式,當A啓動後,系統會爲它建立一個新的任務棧,而後A獨自在這個新的任務棧中,因爲棧內複用的特性,後續的請求均不會建立新的Activity,除非這個獨特的任務棧被系統銷燬了
14.若是一個Activity彈出一個Dialog,那麼這個Acitvity會回調哪些生命週期函數呢?
是否彈出 Dialog,並不影響 Activity 的生命週期,因此這時和正常啓動時 Activity 的生命回調方法一致: onCreate() -> onStart() -> onResume()。
15.Activity之間如何通訊 & Activity和Fragment之間通訊 & Activity和Service之間通訊?
1.Activity->Activity
[1]Intent/Bundle
這種方式多用於Activity之間傳遞數據
[2]類靜態變量
在Activity內部定義靜態的變量,這種方式見於少許的數據通訊,若是數據過多,仍是使用第一種方式
[3]全局變量
建立一個類,裏面定義一批靜態變量,Activity之間通訊均可以訪問這個類裏面的靜態變量,這就是全局變量。
2.Activity->Service
[1]綁定服務的方式,利用ServiceConnection這個接口
[2]Intent
這種方式很簡單,咱們在啓動和中止Service時所調用的方法都須要傳入一個Intent實例對象,經過這個傳入的Intent對象,咱們就能夠與Service進行通訊。
[3]CallBack + Handler,監聽服務的進程變化
3.Activity->Fragment
[1]Bundle
在建立Fragment實例的時候,調用方法setArguments將一個Bundle對象傳遞給Fragment,而後在Fragment中先去判斷是否和當前Activity綁定上了,若是綁定上了,就能夠拿出這個Bundle中的數據
[2]直接進行方法調用
在Activity裏經過Fragment的引用,能夠直接調用Framgent中的定義的任何方法。
16.說說Activity橫豎屏切換的生命週期。
onPause
onSaveInstanceState //這裏能夠用來橫豎屏切換的保存數據
onStop
onDestroy
onCreate
onStart
onRestoreInstanceState//這裏能夠用來橫豎屏切換的恢復數據
onResume
17.前臺切換到後臺,而後在回到前臺時Activity的生命週期。
點擊home鍵回到桌面–>onPause()–>onStop()
再次回到原Activity時–>onRestart()–>onStart()–>onResume()
18.下拉狀態欄時Activity的生命週期?
首先,通知欄下拉一點點,符合通常描述中「Activity被部分遮擋」——onPause()
而後,通知欄徹底落下以後,「Activity被所有遮擋」——onStop()
19.Activity與Fragment的生命週期比較?
onAttach()->onCreate()->onCreateView()->onActivityCreated()->onStart()->onResume();
Fragment變爲不可見狀態(鎖屏、回到桌面、被Activity徹底覆蓋):onPause()->onSaveInstanceState()->onStop();
Fragment變爲部分可見狀態(打開Dialog樣式的Activity):onPause()->onSaveInstanceState();
Fragment由不可見變爲活動狀態:onStart()->OnResume();
Fragment由部分可見變爲活動狀態:onResume();
退出應用:onPause()->onStop()->onDestroyView()->onDestroy()->onDetach()
Fragment被回收又從新建立:被回收執行onPause()->onSaveInstanceState()->onStop()->onDestroyView()->onDestroy()->onDetach(),從新建立執行onAttach()->onCreate()->onCreateView()->onActivityCreated()->onStart()->onResume()->setUserVisibleHint();
橫豎屏切換:與Fragment被回收又從新建立同樣。
20.瞭解哪些Activity經常使用的標記位Flags?
1.Intent.FLAG_ACTIVITY_NEW_TASK,是爲Activity指定「singleTask」啓動模式
2.Intent.FLAG_ACTIVITY_SINGLE_TOP,是爲Activity指定「singleTop」啓動模式
3.FLAG_ACTIVITY_CLEAR_TOP,若是跟singleTask啓動模式一塊兒出現,若是被啓動的Activity已經存在實例,則onNewIntent方法會被回調,若是被啓動的Activity採用standard模式啓動,那麼連同它跟它之上的Activity都要出棧,而且建立新的實例放入棧頂。
4.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS,新的Activity不會在最近啓動的Activity的列表中保存。等同於指定屬性android:excludeFromRecents="true"
21.談談隱式啓動和顯示啓動Activity的方式?
顯式啓動:直接指定要跳轉的Activity類名,不用過濾,效率高,適用於同一個應用中的不一樣Activity跳轉
隱式啓動:須要過濾,相對耗時,但能夠找到全部之匹配的應用。適用於不一樣應用之間的Activity跳轉。
隱式啓動會找到所匹配到的應用,並提示用戶選擇打開方式,若是有多個組件被匹配成功,就會以對話框列表的方式讓用戶進行選擇。
22.Activity用Intent傳遞數據和Bundle傳遞數據的區別?爲何不用HashMap呢?
要把值經過A通過B傳給C
若是用Intent的話 A-B先寫一遍 再在B中都取出來 而後在把值塞到Intent中 再跳到C 累嗎?
若是我在A中用了 Bundle 的話 我把Bundle傳給B 在B中再轉傳到C C就能夠直接去了
這樣的話 還有一個好處 就是在B中 還能夠給Bundle對象添加新的 key - value 一樣能夠在C中取出來
爲何不用HashMap呢?
Bundle內部是由ArrayMap實現的,ArrayMap的內部實現是兩個數組,一個int數組是存儲對象數據對應下標,一個對象數組保存key和value,內部使用二分法對key進行排序,因此在添加、刪除、查找數據的時候,都會使用二分法查找,只適合於小數據量操做,若是在數據量比較大的狀況下,那麼它的性能將退化。而HashMap內部則是數組+鏈表結構,因此在數據量較少的時候,HashMap的Entry Array比ArrayMap佔用更多的內存。由於使用Bundle的場景大多數爲小數據量
在Android中若是使用Intent來攜帶數據的話,須要數據是基本類型或者是可序列化類型,HashMap使用Serializable進行序列化,而Bundle則是使用Parcelable進行序列化。而在Android平臺中,更推薦使用Parcelable實現序列化,雖然寫法複雜,可是開銷更小,因此爲了更加快速的進行數據的序列化和反序列化,系統封裝了Bundle類,方便咱們進行數據的傳輸。
23.在隱式啓動中Intent能夠設置多個action,多個category嗎 & 順便講講它們的匹配規則?
一個Intent對象中最多隻能包括一個Action屬性,但能夠包含多個Category屬性
24.Activity能夠設置爲對話框的形式嗎?
在mainifest中對應的activity上配置以下的代碼,便可讓activity以對話框的方式表現出來
< android:theme="@android:style/Theme.Dialog">
25.如何給Activity設置進入和退出的動畫?
一種是直接在代碼中設置,這須要使用到Activity的overridePendingTransition方法;
另外一種是經過自定義Activity的主題來實現。
26.Activity使用Intent傳遞數據是否有限制 & 若是傳遞一個複雜的對象,例如一個複雜的控件對象應該怎麼作?
1 傳512K如下的數據的數據能夠正常傳遞。
2 傳512K~1024K的數據會出錯,閃退。
3 傳1024K以上的數據會報錯:TransactionTooLargeException。
4 考慮到Intent還包括要啓動的Activity等信息,實際能夠傳的數據略小於512K
若是傳遞一個複雜的對象,例如一個複雜的控件對象應該怎麼作?
1)將對象轉換爲Json字符串
2)使用Serializable,Parcelable序列化對象
1.Serializable實現:
①業務Bean實現:Serializable接口,寫上getter和setter方法
②Intent經過調用putExtra(String name, Serializable value)傳入對象實例 固然對象有多個的話多個的話,咱們也能夠先Bundle.putSerializable(x,x);
③新Activity調用getSerializableExtra()方法得到對象實例: eg:Product pd = (Product) getIntent().getSerializableExtra("Product");
④調用對象get方法得到相應參數
2.Parcelable實現:
通常流程:
①業務Bean繼承Parcelable接口,重寫writeToParcel方法,將你的對象序列化爲一個Parcel對象;
②重寫describeContents方法,內容接口描述,默認返回0就能夠
③實例化靜態內部對象CREATOR實現接口Parcelable.Creator
④一樣式經過Intent的putExtra()方法傳入對象實例,固然多個對象的話,咱們能夠先 放到Bundle裏Bundle.putParcelable(x,x),再Intent.putExtras()便可
3.使用數據庫
2.2 BroadcastReceiver
1.廣播是什麼?
它是一種普遍運用在應用程序之間傳輸信息的機制,Android中咱們發送廣播內容是一個Intent,這個Intent中能夠攜帶咱們要發送的數據。
2.廣播的註冊方式有哪些?
1 靜態註冊:建立一個廣播接收器類,廣播接收器在AndroidManifest.xml文件中註冊
2 動態註冊:新建一個類,讓它繼承自BroadcastReceiver,並重寫父類的onReceive()方法就好了
3.廣播的分類 & 特性 & 使用場景?
3.1 無序廣播
context.sendBroadcast(Intent)方法發送的廣播,不可被攔截,固然發送的數據,接收者是不能進行修改的。
3.2 有序廣播
context.sendOrderBroadcast(Intent)方法發送的廣播,可被攔截,並且接收者是能夠修改其中要發送的數據,修改和添加都是能夠的,這就意味着優先接收者對數據修改以後,下一個接收者接受的數據是上一個接收者已經修改了的,這必須明白。
3.3 本地廣播
localBroadcastManager.sendBroadcast(Intent),只在app內傳播。
4.說說系統廣播和本地廣播的原理 & 區別 & 使用場景。
4.1 系統廣播的源碼角度分析
a.自定義廣播接收者BroadcastReceiver,而且重寫onReceiver()方法。
b.經過Binder機制向AMS(Activity Manager Service)進行註冊。
c.廣播發送者經過Binder機制向AMS發送廣播。
d.AMS查找符合條件(IntentFilter/Permission等)的BroadcastReceiver,將廣播發送到相應的BroadcastReceiver(通常狀況下是Activity)的消息隊列中。
e.消息循環執行拿到此廣播,回調BroadcastReceiver中的onReceiver()方法。
4.2 本地廣播的源碼角度分析
相比於系統廣播而言,本地廣播更加安全,更加高效,如下是本地廣播的特色以及內部的實現機制:
特色:
a.使用它發送的廣播將只在自身app內傳播,所以你沒必要擔憂泄漏隱私的數據。
b.其餘app沒法對你的app發送該廣播,所以你的app根本不可能收到非自身app發送的該廣播,所以你沒必要擔憂有安全漏洞能夠利用。
c.比系統廣播更加高效。
5.有兩個應用註冊了同樣的廣播,一個是靜態,一個是動態,連優先級也同樣,那麼當廣播從系統發出來後,哪一個應用先接收到廣播?
動態註冊的接收者會先執行
2.3 ContentProvider
1.什麼是內容提供者?
(Content Provider)主要用於在不一樣的應用程序之間實現數據共享的功能
2.說說如何建立本身應用的內容提供者 & 使用場景。
新建一個類去繼承ContentProvider類的方式來建立一個本身的內容提供器。ContentProvider類有6個抽象方法,咱們在使用子類繼承它的時候,須要將這6個方法所有重寫。
3.說說ContentProvider的原理。
一種進程間通訊的方式,其實它原理核心就是Binder。
4.ContentProvider,ContentResolver,ContentObserver之間的關係?
ContentProvider——內容提供者, 在android中的做用是對外共享數據,也就是說你能夠經過
ContentProvider把應用中的數據共享給其餘應用訪問,其餘應用能夠經過ContentProvider 對你應用中的數據進行添刪改查。
ContentResolver——內容解析者, 其做用是按照必定規則訪問內容提供者的數據(其實就是調用內容提供者自定義的接口來操做它的數據)。 ContentObserver——內容觀察者,目的是觀察(捕捉)特定Uri引發的數據庫的變化,繼而作一些相應的處理,它相似於數據庫技術中的觸發器(Trigger),當ContentObserver所觀察的Uri發生變化時,便會觸發它
5.說說ContentProvider的權限管理。
android:grantUriPermssions:臨時許可標誌。
android:permission:Provider讀寫權限。
android:readPermission:Provider的讀權限。
android:writePermission:Provider的寫權限。
android:enabled:標記容許系統啓動Provider。
android:exported:標記容許其餘應用程序使用這個Provider。
android:multiProcess:標記容許系統啓動Provider相同的進程中調用客戶端。
2.4 Service
1.什麼是Service?
Service(服務)是一個一種能夠在後臺執行長時間運行操做而沒有用戶界面的組件。它運行於UI線程,所以不能進行耗時的操做。
2.說說Service的生命週期。
bindService:onCreate()-onBind()-unBind()-onDestroy()
這種方式進行啓動service好處是更加便利activity中操做service,經過ServiceConnection來獲取service中內部類的類對象,而後經過這個類對象就能夠調用類中的方法
startService:onCreate()-onStartCommon()-onDestroy()
當咱們經過startService被調用之後,屢次在調用startService(),onCreate()方法也只會被調用一次,而onStartConmon()會被屢次調用
3.Service和Thread的區別?
Service的運行是在UI線程當中的,是絕對絕對不能進行耗時操做的,而Thread開啓的子線程則能夠進行耗時操做,可是Thread開啓的子線程是不能直接對UI進行操做的,不然極有可能發生直接讓程序崩掉,這就是它們的區別。
4.Android 5.0以上的隱式啓動問題及其解決方案。
1 將隱式啓動轉換爲顯式啓動,兼容編譯sdk5.0之後版本
2 直接寫上包名以及標誌
3 判斷應用是否安裝
5.給我說說Service保活方案
1)onStartCommand方法,返回START_STICKY
2)提高service優先級
在AndroidManifest.xml文件中對於intent-filter能夠經過android:priority = "1000"這個屬性設置最高優先級,1000是最高值,若是數字越小則優先級越低,同時適用於廣播。
3)提高service進程優先級
Android中的進程是託管的,當系統進程空間緊張的時候,會依照優先級自動進行進程的回收。Android將進程分爲6個等級,它們按優先級順序由高到低依次是:
複製代碼
1.前臺進程( FOREGROUND_APP)
2.可視進程(VISIBLE_APP )
3.次要服務進程(SECONDARY_SERVER )
4.後臺進程 (HIDDEN_APP)
5.內容供應節點(CONTENT_PROVIDER)
6.空進程(EMPTY_APP)
4)onDestroy方法裏重啓service
5)Application加上Persistent屬性
6.IntentService是什麼 & 原理 & 使用場景 & 和Service的區別。
IntentService是繼承處理異步請求的一個類,在IntentService內有一個工做線程來處理耗時操做,啓動IntentServiced的方式和啓動傳統的Service同樣,同時,當任務執行完成後,IntentService會自動中止,而不須要咱們手動去控制或stopSelf()。
a.它本質是一種特殊的Service,繼承自Service而且自己就是一個抽象類。
b.它內部是由HandlerThread和Handler實現異步操做。
7.建立一個獨立進程的Service應該怎樣作?
建立遠程服務
1)定義AIDL接口
2)新建Remote Service
3)在AndroidManifest.xml中對Remote Service進行配置
8.Service和Activity之間如何通訊?
一、Intent傳值,onStartCommand()接收。
二、經過onBind()獲取Service實例,而後再調用Binder中的相關方法。
三、經過回調函數達到偵聽Service中數據變化。
9.說說你瞭解的系統Service。
https://blog.csdn.net/geyunfei_/article/details/78851024
10.談談你對ActivityManagerService的理解。
從系統運行的角度看,AmS能夠分爲Client端和Service端:Client端運行在各個app進程,app進程實現了具體的Activity,Service等,告訴系統我有那些Activity,Service等,而且調用系統接口來完成顯示;Service端運行在SystemServer進程,是系統級別的ActivityManagerService的具體實現,其響應Client端的系統調用請求,而且管理Client端各個app進程的生命週期。
https://www.cnblogs.com/xingchenkn/p/3637137.html
11.在Activtiy中建立一個Thread和在一個Service中建立一個Thread的區別?
Activtiy中的線程是前臺線程,它的生命週期每每是隨着Activity的,Activity銷燬的時候,那個線程也應該被銷燬,不然就會出現內存泄漏現象。而Service中開啓的線程,它是工做在後臺的,通常來說,後臺線程的生存期是比較長的。
2.5 Handler
1.子線程必定不能更新UI嗎?
是否有些控件支持在子線程更新UI呢?好比:SurfaceViw
在Activity的onResume()生命週期函數以前是能夠在子線程中更新UI的。
2.給我說說Handler的原理
Message:消息,其中包含了消息ID,消息處理對象以及處理的數據等,由MessageQueue統一列隊,終由Handler處理。
Handler:處理者,負責Message的發送及處理。使用Handler時,須要實現handleMessage(Message msg)方法來對特定的Message進行處理,例如更新UI等。
MessageQueue:消息隊列,用來存放Handler發送過來的消息,並按照FIFO規則執行。固然,存放Message並不是實際意義的保存,而是將Message以鏈表的方式串聯起來的,等待Looper的抽取。
Looper:消息泵,不斷地從MessageQueue中抽取Message執行。所以,一個MessageQueue須要一個Looper。
Thread:線程,負責調度整個消息循環,即消息循環的執行場所。
Handler是能夠經過發送和處理Message和Runnable對象來關聯相應線程的MessageQueue。一般咱們認爲它是一種異步機制。
a.可讓對應的Message和Runnable在將來的某個時間點進行相應的處理。
b.讓本身想要的耗時操做在子線程中完成,讓更新UI的操做在主線程中完成,而子線程與主線程之間的通訊就是靠Handler來完成。
3.Handler致使的內存泄露你是如何解決的?
Handler致使內存泄漏的緣由是:非靜態內部類持有外部類的引用,致使外部類在沒有被使用的時候,遲遲不能被回收,從而致使內存泄漏。即非靜態Handler內部類持有外部Activity的引用,致使外部Activity退出/銷燬的時候,它遲遲不能被回收,最終致使Activity的內存泄漏。 解決方法:將Handler類聲明爲靜態,若是Handler須要訪問外部類Activity的成員變量或者成員方法,能夠用弱引用的方式解決。
4.如何使用Handler讓子線程和子線程通訊?
在ThreadA中準備一個Looper,也就是消息輪詢大管家,而後準備發送消息的Handler,準備發送消息的Handler很容易理解,那就是在ThreadA中生成一個Handler對象便可,
那麼準備Looper怎麼作呢?在ThreadA中調用Looper.prepare(),而後再調用Looper.loop()便可
5.你能給我說說Handler的設計原理?
6.HandlerThread是什麼 & 原理 & 使用場景?
a.HandlerThread本質上是一個線程類,它繼承了Thread。
b.HandlerThread有本身內部的Looper對象,能夠進行Looper循環。
c.經過獲取HandlerThread的Looper對象傳遞給Handler對象,能夠在handlerMessage方法中執行異步任務。
d.優勢是不會有堵塞,減小對性能的消耗,缺點是不能進行多任務的處理,須要等待進行處理,處理效率較低。
e.與線程池注重併發不一樣,HandlerThread是一個串行隊列,HandlerThread背後只有一個線程
7.IdleHandler是什麼?
IdleHandler 能夠用來提高性能,主要用在咱們但願可以在當前線程消息隊列空閒時作些事情(譬如 UI 線程在顯示完成後,若是線程空閒咱們就能夠提早準備其餘內容)的狀況下,不過最好不要作耗時操做。
8.一個線程可否建立多個Handler,Handler和Looper之間的對應關係?
一個線程能夠有多個Handler,可是一個線程只能有一個Looper,一個MessageQueue。所以它們之間的關係是一個線程只能有一個Looper,一個MessageQueue,多個Handler。
9.爲何Android系統不建議子線程訪問UI?
UI控件不是線程安全的,若是多線程併發訪問UI控件可能會出現不可預期的狀態
那爲何系統不對UI控件的訪問加上鎖機制呢?
加上鎖機制會讓UI訪問的邏輯變得複雜; 鎖機制會下降UI訪問的效率,由於鎖機制會阻塞某些線程的執行;
10.Looper死循環爲何不會致使應用卡死?
ActivityThread的main方法主要就是作消息循環,一旦退出消息循環,那麼你的應用也就退出了。
11.使用Handler的postDealy後消息隊列有什麼變化?
https://blog.csdn.net/qingtiantianqing/article/details/72783952
12.能夠在子線程直接new一個Handler出來嗎?
1(需先在該線程中手動開啓Looper(Looper.prepare()-->Looper.loop()),而後將其綁定到Handler對象上
2(經過Looper.getMainLooper(),得到主線程的Looper,將其綁定到此Handler對象上
13.Message對象建立的方式有哪些 & 區別?https://blog.csdn.net/dfskhgalshgkajghljgh/article/details/52672115