二、Android面試題
Android面試題包括Android基礎(chǔ)颜骤,還有一些源碼級別的柔袁、原理這些等呆躲。所以想去大公司面試,一定要多看看源碼和實現(xiàn)方式捶索,常用框架可以試試自己能不能手寫實現(xiàn)一下歼秽,鍛煉一下自己。
(一)Android基礎(chǔ)知識點
1情组、四大組件是什么
Activity燥筷、Service箩祥、Content Provider、BroadCast Receiver
2肆氓、四大組件的生命周期和簡單用法
Activity:
Service:
用法:
步驟1:創(chuàng)建子類繼承Service類袍祖。
需要重寫父類的onCreate()、onStartCommond()谢揪、onDestroy()和onBind()方法蕉陋。
步驟2:構(gòu)建用于啟動Service的Intent對象。
步驟3:調(diào)用startService()啟動Service拨扶,調(diào)用stopService()停止服務(wù)凳鬓。
步驟4:在AndroidManifest.xml里邊注冊Service。
Content Provider:
ContentProvider并沒有Activity那樣復(fù)雜的生命周期患民,只有簡單的onCreate過程缩举。ContentProvider是一個抽象類,當(dāng)實現(xiàn)自己的ContentProvider類匹颤,只需要繼承ContentProvider仅孩,并實現(xiàn)以下六個抽象方法。
onCreate():執(zhí)行初始化工作印蓖。
insert(Uri,ContentValues):插入新數(shù)據(jù)辽慕。
delete(Uri,String,String[]):刪除已有數(shù)據(jù)。
update(Uri,ContentValues,String,String[]):更新數(shù)據(jù)赦肃。
query(Uri,String[],String,String[],String):查詢數(shù)據(jù)溅蛉。
getType(Uri):獲取數(shù)據(jù)的MIME類型。
BroadCast Receiver:
動態(tài)注冊的廣播他宛,生命周期僅限于當(dāng)前注冊的Activity温艇,離開Activity時,一定要取消注冊堕汞,否則會拋出異常勺爱,但是該異常不會造成APP崩潰,但會造成內(nèi)存泄漏讯检。離開Activity后琐鲁,即使沒有取消注冊,該廣播也不會再接收消息人灼。
靜態(tài)注冊廣播围段,相比較動態(tài)注冊,即使退出app投放,廣播依然可用奈泪,通過<receiver>標(biāo)簽進(jìn)行靜態(tài)注冊廣播,會在執(zhí)行完onReceive方法后任意時間段內(nèi)銷毀,所以涝桅,我們不需要手動進(jìn)行取消注冊拜姿。
3、Activity之間的通信方式
Intent傳值冯遂。
借助類的靜態(tài)變量蕊肥。
借助全局變量/Application。
借助外部工具(SharePreference蛤肌,SQLLite壁却,F(xiàn)ile,Android剪切板)裸准。
借助Service展东。
4、Activity各種情況下的生命周期
(1)炒俱、Activity第一次啟動生命周期:onCreate-->onStart-->onResume
(2)盐肃、當(dāng)用戶打開新的Activity或切換到桌面時:回調(diào)onPause-->onStop。這里有一個特殊情況向胡,就是當(dāng)打開的Activity是一個透明的Activity時恼蓬,當(dāng)前Activity只會執(zhí)行onPause惊完,不會執(zhí)行onStop僵芹。
(3)、當(dāng)用戶再次回到原Activity時小槐,回調(diào):onRestart-->onStart-->onResume拇派。
(4)、當(dāng)用戶按下Back鍵時凿跳,回調(diào):onPause-->onStop-->onDestroy件豌。
(5)、當(dāng)Activity被系統(tǒng)回收控嗜,再次打開聲明周期與(1)相同茧彤,只是生命周期相同,并不是代表所有過程都一樣疆栏。
(6)曾掂、從這個生命周期來說,onCreate與onDestroy是配對的壁顶,分別標(biāo)識著Activity的創(chuàng)建和銷毀珠洗,并且只可能調(diào)用一次。
5若专、橫豎屏切換的時候许蓖,Activity 各種情況下的生命周期
(1)、不設(shè)置Activity的Android:configChanges時,切屏?xí)匦抡{(diào)用生命周期膊爪,切橫屏?xí){(diào)用一次自阱,切豎屏?xí){(diào)用兩次。
(2)蚁飒、設(shè)置Activity的Android:configChanges="orientation"時动壤,切屏還是會重新調(diào)用生命周期,切橫豎屏都只調(diào)用一次生命周期淮逻。
(3)琼懊、設(shè)置Activity的Android:configChanges="orientation|keyboardHidden|screenSize"時,切屏不會重新調(diào)用各個生命周期爬早,只會調(diào)用onConfigurationChanged方法哼丈。
6、Activity與Fragment之間生命周期比較
Fragment生命周期:
onAttach()
onCreate()
onCreateView()
onActivityCreate()? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ---以上相當(dāng)于Activity的onCreate方法筛严。
onStart()? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ---相當(dāng)于Activity的onStart方法
onResume() ---相當(dāng)于Activity的onResume方法
onPause() ---相當(dāng)于Activity的onPause方法
onStop() ---相當(dāng)于Activity的onStop方法
onDestroyView()
onDestroy()
onDetach() ---相當(dāng)于Activity的onDestroy方法醉旦。
7、Activity上有Dialog的時候按Home鍵時的生命周期
無論頁面上是否有Dialog桨啃,按下Home鍵時都會回調(diào):onPause-->onStop
8车胡、兩個Activity 之間跳轉(zhuǎn)時必然會執(zhí)行的是哪幾個方法?
當(dāng)從ActivityA跳轉(zhuǎn)到ActivityB時照瘾,A會調(diào)用onPause()匈棘,然后B調(diào)用onCreate(),onStart()析命,onResume()主卫,然后B此時覆蓋在A只是,A調(diào)用onStop()方法鹃愤。
如果B是透明窗口簇搅,或?qū)υ捒驑邮剑筒粫{(diào)用A的onStop()方法软吐。
如果B已經(jīng)存在在Activity棧中瘩将,B就不會調(diào)用onCreate()方法。
9凹耙、前臺切換到后臺姿现,然后再回到前臺,Activity生命周期回調(diào)方法使兔。彈出Dialog建钥,生命值周期回調(diào)方法。
前臺切換到后臺虐沥,回調(diào):onPause-->onStop
再回到前臺熊经,回調(diào):onRestart-->onStart-->onResume
彈出Dialog泽艘,回調(diào):onPause
10、Activity的四種啟動模式對比
Activity四種啟動模式:standard镐依、singleTop匹涮、singleTask、singleInstance
standard:標(biāo)準(zhǔn)模式槐壳,這也是系統(tǒng)默認(rèn)模式然低。每次啟動Activity都會創(chuàng)建一個實例,不管這個實例是否已存在务唐。
singleTop:棧頂復(fù)用模式雳攘。在這種模式下,如果新的Activity已經(jīng)存在于任務(wù)棧的棧頂枫笛,那么此Activity的實例不會被重新創(chuàng)建吨灭,同時它的onNewIntent方法會被回調(diào)。注意:這個Activity的onCreate刑巧、onStart方法并不會被系統(tǒng)調(diào)用喧兄,因為它沒有發(fā)生改變;如果新的Activity的實例已存在啊楚,但并不在棧頂吠冤,那么會重新創(chuàng)建新的Activity實例。
singleTask:棧內(nèi)復(fù)用模式恭理。這是一種單實例模式拯辙,如果任務(wù)棧內(nèi)存在該Activity的實例,那么就將這個實例之上的所有Activity出棧蚯斯,將這個新的Activity實例置于棧頂薄风。
singleInstance:單實例模式饵较。這是一種加強(qiáng)版的singleTask拍嵌,此模式的Activity只能單獨運行在一個任務(wù)棧中。
11循诉、Activity狀態(tài)保存于恢復(fù)
(1)横辆、onSaveInstanceState()方法用來在Activity被強(qiáng)制銷毀之前保存數(shù)據(jù),onSaveInstanceState()方法攜帶一個Bundle類型的參數(shù)茄猫,Bundle提供了一系列方法用于保存數(shù)據(jù)狈蚤。
(2)、onRestoreInstanceState()方法用來取的之前再onSaveInstanceState()方法中保存的值划纽。
12脆侮、fragment各種情況下的生命周期
(1)、Fragment在Activity中replace
新替換的Fragment:onAttach-->onCreate-->onCreateView-->onViewCreated-->onActivityCreated-->onStart-->onResume
被替換的Fragment:onPause-->onStop-->onDestroyView-->onDestroy-->onDestach
(2)勇劣、Fragment在Activity中replace并addToBackStack
新替換的Fragment(沒有在BackStack中):onAttach-->onCreate-->onCreateView-->onViewCreated-->onActivityCreated-->onStart-->onResume
新替換的Fragment(在BackStack中):onCreateView-->onViewCreated-->onActivityCreated-->onStart-->onResume
被替換的Fragment:onPause-->onStop-->onDestroyView
(3)靖避、Fragment在上述情況下進(jìn)入onResume后潭枣,則進(jìn)入了運行狀態(tài)弦撩,以下四個生命周期將跟隨所屬的Activity一起調(diào)用:
onPause > onStop > onStart > onResume
13氮发、Fragment狀態(tài)保存startActivityForResult是哪個類的方法,在什么情況下使用诈铛?
Fragment調(diào)用startActivityForResult--->HostCallbacks.onStartActivityFromFragment--->Fragment.startActivityFromFragment篡九。
14谐岁、如何實現(xiàn)Fragment的滑動?
ViewPager嵌套Fragment即可實現(xiàn)滑動榛臼。
15伊佃、fragment之間傳遞數(shù)據(jù)的方式?
(1)沛善、在創(chuàng)建的Fragment添加tag锭魔,使用bundle傳值。
(2)路呜、使用接口回調(diào)傳值迷捧。
(3)、使用開源的EventBus傳值胀葱。
16漠秋、Activity 怎么和Service 綁定?
實現(xiàn)Service的onBind()方法以返回Service的實例給Activity抵屿。
17庆锦、怎么在Activity 中啟動自己對應(yīng)的Service?
Activity通過bindService()跟Service綁定轧葛。
綁定成功后搂抒,Service會將代理對象通過回調(diào)的形式傳遞給MyServiceConnection,這樣我們就獲得了Service提供的代理對象尿扯。
18求晶、service和activity怎么進(jìn)行數(shù)據(jù)交互?
(1)衷笋、binder+回調(diào)(listener)
主要思路:Activity將實例傳入Service芳杏,同時利用回調(diào)更新UI。
(2)辟宗、binder+Handler
主要思路:Service持有Activity的Handler對象爵赵,Service通過往該Handler send message的方式,達(dá)到通信的目的泊脐。
(3)空幻、廣播(推薦LocalBroadCastManager)
主要思路:利用系統(tǒng)的LocalBroadCastManager、Service send message容客,Activity receive message;
(4)秕铛、開源組件(EventBus则剃,otto)
(5)、AIDL
19如捅、Service的開啟方式
(1)棍现、采用start啟動方式
步驟:定義一個類繼承Service
? 在Manifest.xml中配置Service
? 使用Context的startService(Intent)方法啟動Service
? 不再使用時,使用stopService(Intent)方法停止Service
特點:
一旦服務(wù)開啟跟調(diào)用者(開啟者)就沒有關(guān)系了镜遣。
開啟者退出己肮,開啟者掛了,服務(wù)還在后臺長期的運行悲关。
開啟者不能調(diào)用服務(wù)里的方法谎僻。
(2)、使用bind啟動方式
步驟:定義一個類繼承Service
? ? 在Manifest.xml中配置Service
? ? 使用Context的bindService(Intent,ServiceConnection,int)方法啟動該Service
? ? 不再使用時寓辱,調(diào)用unbindService(ServiceConnection)方法停止服務(wù)艘绍。
20、請描述一下Service 的生命周期
21秫筏、談?wù)勀銓ontentProvider的理解
ContentProvider一般為存儲和獲取數(shù)據(jù)提供統(tǒng)一的接口诱鞠,可以再不同的應(yīng)用程序之間共享數(shù)據(jù)。
之所以使用ContentProvider的原因:
(1)这敬、ContentProvider提供了對底層數(shù)據(jù)存儲方式的抽象航夺。比如下圖,底層使用SQLite數(shù)據(jù)庫崔涂,在用了ContentProvider封裝后阳掐,即使把數(shù)據(jù)庫換成MongoDB,也不會對上層數(shù)據(jù)使用層代碼產(chǎn)生影響冷蚂。
(2)缭保、Android框架中的一些類需要ContentProvider類型的數(shù)據(jù)。
(3)蝙茶、ContentProvider為應(yīng)用間提供了一個安全的環(huán)境艺骂。它準(zhǔn)許你把自己的應(yīng)用的數(shù)據(jù)根據(jù)需求開放給其他應(yīng)用進(jìn)行增、刪尸闸、改彻亲、查孕锄,而不用擔(dān)心直接開放數(shù)據(jù)庫權(quán)限而帶來的安全問題吮廉。
22、說說ContentProvider畸肆、ContentResolver宦芦、ContentObserver 之間的關(guān)系
ContentProvider的作用是實現(xiàn)各個應(yīng)用程序之間的(跨應(yīng)用)數(shù)據(jù)共享。
一個應(yīng)用實現(xiàn)ContentProvider來提供內(nèi)容給別的應(yīng)用來操作轴脐,通過ContentResolver來操作別的應(yīng)用的數(shù)據(jù)调卑,當(dāng)然在自己的應(yīng)用中也是可以的抡砂。
ContentObserver-----內(nèi)容觀察者,目的是觀察特定Uri引起的數(shù)據(jù)庫的變化恬涧,繼而做一些相應(yīng)的處理注益,它類似于數(shù)據(jù)庫技術(shù)中的觸發(fā)器,當(dāng)ContentObserver所觀察的Uri發(fā)生變化時溯捆,便會觸發(fā)它丑搔。
23、請描述一下廣播BroadcastReceiver的理解
廣播即一個全局的監(jiān)聽器提揍,屬于Android四大組件啤月。
Android廣播分為兩個角色:廣播發(fā)送者,廣播接收者劳跃。
應(yīng)用場景:
Android不同組件間的通信(含:應(yīng)用內(nèi)/不同應(yīng)用之間的)谎仲。
多線程通信。
與Android系統(tǒng)在特定情況下的通信刨仑。(如電話呼入時郑诺,網(wǎng)絡(luò)可用時)
采用的模型:
Android中的廣播采用了設(shè)計模式中的觀察者模式:基于消息的發(fā)布/訂閱事件模型。
模型中的角色:
消息訂閱者(廣播接收者)
消息發(fā)布者(廣播發(fā)送者)
消息中心(AMS杉武,即Activity Manager Service)
24间景、廣播的分類
普通廣播
系統(tǒng)廣播
有序廣播
粘性廣播
App應(yīng)用內(nèi)廣播
25、廣播使用的方式和場景
(1)艺智、靜態(tài)注冊
步驟:定義一個廣播接收器(繼承BroadcastReceiver)
? ? 在清單文件中注冊該廣播接收器? ?
? ? ?在java程序中使用廣播
(2)倘要、動態(tài)注冊
步驟:定義一個廣播接收器(繼承BroadcastReceiver)
? ? 動態(tài)注冊廣播及使用
解除廣播
在清單文件中注冊該廣播。
26十拣、在manifest 和代碼中如何注冊和使用BroadcastReceiver?
同上封拧。
27、本地廣播和全局廣播有什么差別夭问?
全局廣播:BroadcastReceiver是針對應(yīng)用間泽西、應(yīng)用與系統(tǒng)間、應(yīng)用內(nèi)部進(jìn)行通信的一種方式
本地廣播:LocalBroadcaseReceiver僅在自身應(yīng)用內(nèi)發(fā)送接收廣播缰趋,也就是只有自己的應(yīng)用能收到捧杉,數(shù)據(jù)更加安全,廣播只在這個程序里秘血,而且效率更高
28味抖、BroadcastReceiver,LocalBroadcastReceiver 區(qū)別
同上灰粮。
29仔涩、AlertDialog,popupWindow,Activity區(qū)別
AlertDialog:用來提示用戶一些信息,用起來也比較簡單粘舟,設(shè)置標(biāo)題內(nèi)容和按鈕即可熔脂。
popupWindow:就是一個懸浮在Activity上的窗口佩研,可以用來展示任意布局。
activity:Activity是Android四大組件之一霞揉,可以用于顯示View旬薯。Activity是一個與用戶交互的模塊。
AlertDialog是非阻塞式對話框适秩,AlertDialog彈出時袍暴,后臺還可以做事情;popupWindow是阻塞式對話框隶症,popupWindow彈出時政模,程序會等待,在popupWindow退出前蚂会,程序一致處于等待淋样,只有當(dāng)我們調(diào)用了dismiss方法后,popupWindow退出胁住,程序才會向下執(zhí)行趁猴。
30、Application 和 Activity 的 Context 對象的區(qū)別
凡是跟UI相關(guān)的彪见,都應(yīng)該使用Activity作為Context來處理儡司;其他的一些操作,Service余指,Activity捕犬,Application等實例都可以。
31酵镜、Android屬性動畫特性
(1)碉碉、作用對象進(jìn)行了擴(kuò)展:不只是View對象,甚至沒有對象也可以淮韭。
(2)垢粮、動畫效果:不只是4種基本變換,還有其他動畫效果靠粪。
(3)蜡吧、作用領(lǐng)域:API11之后引入的。
32占键、如何導(dǎo)入外部數(shù)據(jù)庫?
(1)昔善、將格式為.db的數(shù)據(jù)庫文件放到android項目assets目錄中;
(2)捞慌、在程序必要的時候耀鸦,將其“拷貝”(文件讀取)到Android程序的默認(rèn)的數(shù)據(jù)庫存儲目錄中啸澡,一般路徑為“data/data/項目包名/databases/”袖订;
(3)、自定義SQLiteOpenHelp類嗅虏,創(chuàng)建一個名字和步驟(1)中一樣的數(shù)據(jù)庫洛姑;
(4)、按照平常的邏輯皮服,對數(shù)據(jù)庫進(jìn)行增刪改查楞艾。
33、LinearLayout龄广、RelativeLayout硫眯、FrameLayout的特性及對比,并介紹使用場景择同。
(1)两入、RelativeLayout會讓子View調(diào)用兩次onMeasure,LinearLayout在有weight時敲才,也會調(diào)用子View兩次onMeasure裹纳。
(2)、RelativeLayout的子View如果高度和RelativeLayout不同紧武,則會引發(fā)效率問題剃氧,當(dāng)子View很復(fù)雜的時候,這個問題會更加嚴(yán)重阻星。如果可以盡量使用padding代替margin朋鞍。
(3)、在不影響層級深度的情況下妥箕,使用LinearLayout和FrameLayout而不是RelativeLayout番舆。
(4)、能用兩層LinearLayout矾踱,盡量用一個RelativeLayout恨狈,在時間上此時RelativeLayout消耗更小。
34呛讲、談?wù)剬涌谂c回調(diào)的理解
接口回調(diào):可以把使用實現(xiàn)了某一接口的類創(chuàng)建的對象的引用禾怠,賦給該接口聲明的接口變量,那么該接口變量就可以調(diào)用被類實現(xiàn)的接口方法贝搁。實際上吗氏,當(dāng)接口變量調(diào)用被類實現(xiàn)的接口方法時,就是通知響應(yīng)的對象調(diào)用接口的方法雷逆,這一過程稱為對象功能的接口回調(diào)弦讽。
35、回調(diào)的原理
(1)、定義回調(diào)接口往产,定義回調(diào)方法被碗;
(2)、定義要設(shè)置回調(diào)機(jī)制的類仿村,并是此類持有回調(diào)接口的指針锐朴;
(3)、在該類中初始化回調(diào)接口指針蔼囊,并使用指針調(diào)用回調(diào)方法焚志;
(4)、在該類中設(shè)置觸發(fā)時機(jī)及執(zhí)行的觸發(fā)事件函數(shù)畏鼓。
36酱酬、寫一個回調(diào)demo
37、介紹下SurfView
SurfaceView指一個在表層的View對象云矫。其他View是繪制在表層的上面膳沽,而SurfaceView充當(dāng)表層本身。
38泼差、RecycleView的使用
https://blog.csdn.net/weixin_42190712/article/details/80404757
39贵少、序列化的作用,以及Android兩種序列化的區(qū)別
序列化:將對象轉(zhuǎn)換為字節(jié)流
(1)堆缘、在使用內(nèi)存的時候滔灶,Parcelable比Serializable性能高,所以推薦使用Parcelable吼肥。
(2)录平、Serializable在序列化的時候會產(chǎn)生大量的臨時變量,從而引起頻繁的GC缀皱。
(3)斗这、Parcelable不能使用在要將數(shù)據(jù)存儲在磁盤上的情況,因為Parcelable不能很好的保證數(shù)據(jù)的持續(xù)性啤斗,在外界有變化的情況下表箭。盡管Serializable效率有點低,但是還是推薦使用Serializable钮莲。
(4)免钻、Serializable實現(xiàn),只需要implements Serializable即可崔拥,這是給對象打一個標(biāo)記极舔,系統(tǒng)會自動將其序列化。
(5)链瓦、Parcelable實現(xiàn)拆魏,不僅需要implements Parcelable,還需要在類中添加一個靜態(tài)成員變量CREATOR,這個變量要實現(xiàn)Parcelable.Ccreator接口渤刃。
(6)拥峦、Parcelable性能比Serializable好,在內(nèi)存開銷方面比較小溪掀,所以在內(nèi)存間數(shù)據(jù)傳輸時事镣,推薦使用Parcelable步鉴,如:Activity之間傳值揪胃;而Serializable在數(shù)據(jù)持久化方面方便保存,在網(wǎng)絡(luò)中傳輸時氛琢,使用Serializable喊递,因為android不同版本的Parcelable可能不同,所以不推薦使用Parcelable做數(shù)據(jù)持久化阳似。
40骚勘、差值器
Interpolator負(fù)責(zé)控制動畫變化的速率,使得基本動畫能夠以勻速撮奏、加速俏讹、減速、拋物線速率等各種速率變化畜吊。
41泽疆、估值器
TypeEvaluator設(shè)置屬性值,從初始值過度到結(jié)束值的變化具體數(shù)值玲献。
42殉疼、Android中數(shù)據(jù)存儲方式
(1)、使用SharePreference存儲
(2)捌年、使用文件存儲
(3)瓢娜、SQLite數(shù)據(jù)庫存儲
(4)、使用ContentProvider存儲數(shù)據(jù)
(5)礼预、使用網(wǎng)絡(luò)存儲眠砾。
(二)Android源碼相關(guān)分析
1、Android動畫框架實現(xiàn)原理
實現(xiàn)原理:每次繪制View時托酸,ViewGroup中的drawChild函數(shù)獲取該View的Animation的Transformation值褒颈,然后調(diào)用canvas.concat(transformToApply.getMatrix()),通過矩陣運算完成幀動畫获高,如果動畫沒有完成哈肖,就繼續(xù)調(diào)用invalidate()函數(shù),啟動下次繪制來驅(qū)動動畫念秧,從而完成整個動畫的繪制淤井。
當(dāng)一個ChildView要重畫時,它會調(diào)用其他成員函數(shù)invalidate()函數(shù)將通知其ParentView這個ChildView要重畫。
這個過程一直遍歷到ViewRoot币狠,當(dāng)ViewRoot收到這個通知后就會調(diào)用上面提到的ViewRoot中的draw函數(shù)從而完成繪制游两。
Android動畫就是通過ParentView來不斷調(diào)整ChildView的畫布坐標(biāo)系來實現(xiàn)的。
https://blog.csdn.net/qq_32816979/article/details/79746150
2漩绵、Android各個版本API的區(qū)別
https://blog.csdn.net/qq_21399461/article/details/80277472
3贱案、Requestlayout,onlayout止吐,onDraw宝踪,DrawChild區(qū)別與聯(lián)系
requestLayout會導(dǎo)致調(diào)用measure()過程和layout()過程。說明:只是對View樹重新布局layout過程包括measure()過程和layout()過程碍扔,不會調(diào)用draw()過程瘩燥,但不會重新繪制任何視圖包括該調(diào)用者本身。
onLayout()方法(如果該View是ViewGroup對象不同,需要實現(xiàn)該方法厉膀,對每個子視圖進(jìn)行布局。)
調(diào)用onDraw()方法繪制視圖本身(每個視圖都需要重載該方法二拐,ViewGroup不需要實現(xiàn)該方法服鹅。)
drawChild()主要是draw viewGroup中的某個View
4、invalidate和postInvalidate的區(qū)別及使用
Android中實現(xiàn)View的更新有兩組方法百新,一組是invalidate企软,另外一組是postInvalidate,其中前者是在UI線程自身中使用吟孙,而后者是在非UI線程中使用澜倦。
invalidate是在handler中使用,postInvalidate可以直接在子線程中調(diào)用更新View杰妓。
5藻治、Activity-Window-View三者的差別
Activity是Android四大組件之一,負(fù)責(zé)界面展示巷挥、用戶交互和邏輯處理桩卵。
Window就是負(fù)責(zé)界面展示以及交互的只能部門,就相當(dāng)于Activity的下屬倍宾,Activity的生命周期方法負(fù)責(zé)業(yè)務(wù)的處理雏节。
View就是放在Window容器的元素,Window是View的載體高职,View是Window的具體展示钩乍。
6、談?wù)剬olley的理解
Volley是Google推出的輕量級Android異步網(wǎng)絡(luò)請求框架和圖片加載框架怔锌。其適用于數(shù)據(jù)量小寥粹,通信頻繁的網(wǎng)絡(luò)操作变过。
主要特點:
(1)、擴(kuò)展性強(qiáng)涝涤。Volley大多數(shù)是基于接口的設(shè)計媚狰,可配置性強(qiáng)。
(2)阔拳、一定程度符合Http規(guī)范崭孤,包括返回ResponseCode(2xx,3xx,4xx,5xx)的處理,請求頭的處理糊肠,緩存機(jī)制的支持等妨马。并支持重試及優(yōu)先級定義我纪。
(3)龟糕、默認(rèn)Android2.3及以上基于HttpURLConnection宇攻,2.3以下基于HttpClient實現(xiàn)捺宗。
(4)捉兴、提供簡便的圖片加載工具变骡。
7茴肥、如何優(yōu)化自定義View
(1)还最、硬件加速就是使用GPU來代替CPU完成繪制的計算工作墓阀,它從工作分?jǐn)偅屠L制機(jī)制優(yōu)化來提升繪制速度拓轻。
(2)斯撮、如果我們在自定義View的時候,繪制操作不支持硬件加速扶叉,那么我們可以在自定義View中手動關(guān)閉硬件加速勿锅。
8、低版本SDK如何實現(xiàn)高版本api枣氧?
Android提供了兩種注解方式避免編譯時報錯溢十。
@SuppressLint
@TargetApi
SuppressLint很顯然的意思是忽略Lint檢查,對于我們使用高版本的API來說达吞,可以使用@SuppressLint("NewApi")的方式讓Lint在編譯時忽略所調(diào)用的API對版本的要求张弛。而@TargetApi是忽略特定版本的API調(diào)用報錯。
9酪劫、描述一次網(wǎng)絡(luò)請求的流程
(1)吞鸭、通過URL找到IP
(2)、對IP結(jié)果建立TCP連接
(3)覆糟、向服務(wù)器發(fā)送數(shù)據(jù)
(4)刻剥、服務(wù)器解析,并返回
(5)滩字、瀏覽器解析HTML
10造虏、HttpUrlConnection 和 okhttp關(guān)系
HttpUrlConnection是一種多用途盯滚、輕量級的HTTP客戶端,使用它來進(jìn)行HTTP操作可以適用于大多數(shù)應(yīng)用程序酗电。雖然HttpUrlConnection的API提供的比較簡單魄藕,但是,同時使得我們可以更加容易地使用和擴(kuò)展它撵术。從Android4.4開始HttpUrlConnection的底層采用的就是okHttp背率。
okhttp是高性能的http庫,支持同步嫩与、異步寝姿,而且實現(xiàn)了spdy,http2划滋,websocket協(xié)議饵筑,api很簡潔易用,和volley一樣實現(xiàn)了http協(xié)議的緩存处坪。picasso就是利用okhttp的緩存機(jī)制實現(xiàn)其文件緩存的根资,實現(xiàn)的很優(yōu)雅,很正確同窘;反例就是UIL(universal image loader)玄帕,自己做的文件緩存,而且不遵守http緩存機(jī)制想邦。
11裤纹、Bitmap對象的理解
Bitmap的構(gòu)造方法不是共有的,因此外部不能通過new的方式來創(chuàng)建丧没,不過可以Bitmap的createBitmap方法和BitmapFactory鹰椒。
12、looper架構(gòu)
有消息循環(huán)的線程一般都會有一個looper呕童。
Looper.myLooper()漆际;獲取當(dāng)前的Looper。
Looper.getMainLooper()拉庵;獲取UI線程的Looper灿椅。
如果一個線程調(diào)用Looper.prepare(),那么系統(tǒng)就會自動為該線程建立一個消息隊列钞支,然后調(diào)用Looper.loop()茫蛹;之后就進(jìn)入了消息循環(huán),這個之后就可以發(fā)消息烁挟、取消息婴洼、和處理消息。這個如何發(fā)送消息和如何處理消息可以再其他線程中通過Handle來做撼嗓。
13柬采、ActivityThread欢唾,AMS,WMS的工作原理
AMS:統(tǒng)一調(diào)度所有應(yīng)用程序的Activity粉捻。
WMS:控制所有的Window的顯示與隱藏以及要顯示的位置礁遣。
ActivityThread:Android應(yīng)用主線程(UI線程)。
工作原理:
ActivityThread創(chuàng)建完新的進(jìn)程后肩刃,main函數(shù)被加載祟霍,然后執(zhí)行一個loop循環(huán)使當(dāng)前線程進(jìn)入消息循環(huán),并作為主線程盈包。接下來還會初始化很多必要的屬性沸呐。
AMS:AMS從系統(tǒng)運行的角度來看,AMS可以分為Client端和Server端呢燥;
Client端運行在各個app進(jìn)程崭添,app進(jìn)程實現(xiàn)了具體的Activity,Service等叛氨,告訴系統(tǒng)有哪些Activity呼渣、Service等,并且調(diào)用系統(tǒng)接口來完成顯示力试。
Server端運行在SystemServer進(jìn)程徙邻,是系統(tǒng)級別的ActivityManagerService的具體實現(xiàn),其相應(yīng)Client端的系統(tǒng)調(diào)用請求畸裳,并且管理Client端各個App進(jìn)程的生命周期。
WMS:為窗口分配Surface淳地。
? ? 管理Surface的顯示順序怖糊、尺寸和位置
? ? 管理窗口動畫
? ? 輸入系統(tǒng)相關(guān)
14、自定義View如何考慮機(jī)型適配
(1)颇象、盡量使用warp_parent伍伤、match_parent。
(2)遣钳、盡可能的使用RelativeLayout扰魂。
(3)、針對不同的機(jī)型蕴茴,使用不同的布局文件放在對應(yīng)的目錄下劝评,android會自動匹配。
(4)倦淀、盡量使用點9的圖片蒋畜。
(5)、使用與密度無關(guān)的像素單位dp撞叽、sp姻成。
(6)插龄、引入android的百分比布局。
(7)科展、切圖的時候切大分辨率的圖均牢,應(yīng)用到布局中,在小分辨率的手機(jī)上也會有很好的顯示才睹。
15膨处、自定義View的事件
以點擊事件為例
(1)、一個監(jiān)聽內(nèi)部的接口砂竖,OnItemSelectListener真椿。
(2)、接口內(nèi)部有一個onItemSelect方法乎澄,Activity中使用時突硝,通過重寫該方法來實現(xiàn)事件的監(jiān)聽。
(3)置济、在控件中定義一個OnItemSelectListener接口的對象解恰,并設(shè)置set方法。
16浙于、AstncTask+HttpClient 與 AsyncHttpClient有什么區(qū)別护盈?
AsyncHttpClient來自android-async-http庫是在Apach的HttpClient庫的基礎(chǔ)上開發(fā)構(gòu)建而成的,這里的異步羞酗,是指它所有的網(wǎng)絡(luò)請求都是在app的UI線程之外的獨立工作線程中執(zhí)行腐宋。而開發(fā)者通過利用Android的消息處理機(jī)制,把我們所編寫的回調(diào)函數(shù)放在這個回調(diào)函數(shù)的創(chuàng)建線程中執(zhí)行(一般是UI線程)檀轨,所以使用起來非常方便胸竞,除了能用在開發(fā)普通App以外,還可以用來開發(fā)Service或后臺線程参萄,android-async-http庫可以自己分辨是被用在哪種應(yīng)用下卫枝,不需要額外設(shè)置。
17讹挎、LaunchMode應(yīng)用場景
standard模式:默認(rèn)啟動模式校赤,每次啟動Activity都會創(chuàng)建Activity的實例,并放入任務(wù)棧筒溃。
singleTop模式:棧頂模式马篮,每次啟動Activity如果Activity的實例正好處于棧頂,則重用該實例铡羡,否則积蔚,創(chuàng)建新的Activity實例,并放入任務(wù)棧烦周。
singleTask模式:棧內(nèi)模式尽爆,啟動Activity怎顾,如果Activity的實例存在于棧內(nèi),則將該實例上部的所有Activity出棧漱贱,該實例處于棧頂槐雾,如果不存在,則創(chuàng)建新的實例幅狮,并放入任務(wù)棧募强。
singleInstance模式:棧內(nèi)單例模式,每次啟動Activity崇摄,都會重新創(chuàng)建一個新的任務(wù)棧擎值,并創(chuàng)建實例放入該任務(wù)棧。
https://blog.csdn.net/android_freshman/article/details/52948124
18逐抑、AsyncTask 如何使用?
(1)鸠儿、新建內(nèi)部類繼承AsyncTask。
(2)厕氨、定義AsyncTask的三種泛型參數(shù)进每。
(3)、重寫doInBackground抽象方法命斧。
(4)田晚、重寫onPreExecute抽象方法。
(5)国葬、重寫onProgressUpdate方法贤徒。
(6)、重寫onPostExecute方法胃惜。
(7)泞莉、在需要啟動的地方調(diào)用execute()方法。
19船殉、SpareArray原理
SpareArray采用兩個數(shù)組,用來存放key以及value值斯嚎,核心思想就是通過折半查找來找到key對應(yīng)的位置利虫,然后取出值,或者插入值堡僻。
20糠惫、請介紹下ContentProvider 是如何實現(xiàn)數(shù)據(jù)共享的?
(1)钉疫、定義自己的ContentProvider類硼讽,該類需要繼承android系統(tǒng)自帶的ContentProvider類。
(2)牲阁、在Manifest.xml中注冊ContentProvider固阁。
(3)壤躲、其他程序使用ContentResolver來操作。
21备燃、Android Service與Activity之間通信的幾種方式
(1)碉克、Activity調(diào)用bindService(Intent service,ServiceConnection conn,int flags)方法,得到Service對象的一個引用并齐,這樣Activity可以直接調(diào)用到Service中的方法漏麦,如果要主動通知Activity,我們可以利用回調(diào)的方法况褪。
(2)撕贞、Service向Activity發(fā)送消息,可以使用廣播测垛,當(dāng)然Activity要注冊相應(yīng)的廣播接收器捏膨。比如,Service向多個Activity發(fā)送消息的時候赐纱,用這種方法更好脊奋。
22、IntentService原理及作用是什么疙描?
IntentService是繼承于Service并處理異步請求的一個類诚隙,在IntentService中有一個工作線程來處理耗時操作,啟動IntentService的方式和啟動傳統(tǒng)Service一樣起胰,同時久又,當(dāng)任務(wù)完成后,IntentService會自動停止效五,而不需要我們?nèi)ナ謩涌刂频叵A硗猓梢詥覫ntentService多次畏妖,而每一個耗時操作會以工作隊列的方式在IntentService的onHandleIntent回調(diào)方法中執(zhí)行脉执,并且,每次只會執(zhí)行一個工作線程戒劫,執(zhí)行完第一個半夷,再執(zhí)行第二個,以此類推迅细。
作用:
(1)巫橄、省去了在Service中手動開啟線程的麻煩;
(2)茵典、當(dāng)操作完成時湘换,不需要手動停止Service;
(3)、方便使用彩倚。
23筹我、說說Activity、Intent署恍、Service 是什么關(guān)系
(1)崎溃、一個Activity通常是一個單獨的屏幕,每一個Activity都被實現(xiàn)為一個單獨的類盯质,這些類都是從Activity基類中繼承而來袁串。Activity類會顯示由視圖控件組成的用戶接口,并對視圖控件的事件作出響應(yīng)呼巷。
(2)囱修、Intent的調(diào)用是用于屏幕間的切換。Intent描述應(yīng)用想要做什么王悍。Intent數(shù)據(jù)結(jié)構(gòu)中兩個最重要的部分是動作和動作對應(yīng)的數(shù)據(jù)破镰。
(3)、Service是運行在后臺的組件压储,不于用戶進(jìn)行交互鲜漩,可以運行在自己的進(jìn)程中,也可以運行在其他程序的上下文中集惋。需要一個Context對象調(diào)用孕似。
(4)、Activity與Service都是四大組件之一刮刑,存在相同的基類喉祭,他們之間互相調(diào)用需要通過Intent攜帶信息,即Intent相當(dāng)于一個消息傳送者雷绢。
24泛烙、ApplicationContext和ActivityContext的區(qū)別
首先Activity.this和getApplicationContext()返回的不是同一個對象,一個是當(dāng)前Activity的實例翘紊,一個是項目的Application的實例蔽氨,它們各自的使用場景不同,this.getApplicationContext()取的是這個應(yīng)用程序的Context帆疟,它的生命周期伴隨著應(yīng)用程序的存在而存在孵滞;而Activity.this取的是當(dāng)前Activity的實例,它的生命周期只存活于當(dāng)前Activity鸯匹,這兩者的生命周期是不同的。getApplicationContext()生命周期是整個應(yīng)用泄伪,當(dāng)應(yīng)用程序銷毀時殴蓬,它才銷毀;Activity.this的生命周期是這個Activity,當(dāng)Activity銷毀時染厅,它也銷毀痘绎。
25、SP是進(jìn)程同步的嗎?有什么方法做到同步肖粮?
一個進(jìn)程時孤页,可以用SP存儲,但不支持多進(jìn)程涩馆,因為它是基于單個文件的行施,且app對SP做了緩存,不好同步魂那。
考慮用ContentProvider讓SharePreference實現(xiàn)進(jìn)程同步蛾号。
(1)、ContentProvider每次操作都會getSP()涯雅,保證SP的一致性鲜结。
(2)、ContentProvider基于Binder活逆,不存在進(jìn)程互斥精刷,對同步也做了很好的封裝,不需要開發(fā)者額外實現(xiàn)蔗候。
26怒允、談?wù)劧嗑€程在Android中的使用
在項目中比較常用的多線程操作:
(1)、Handler
(2)琴庵、AsyncTask
(3)误算、IntentService
27、進(jìn)程和 Application 的生命周期
進(jìn)程的生命周期迷殿,優(yōu)先級從高到底
(1)儿礼、前臺進(jìn)程,比如Activity的Resume狀態(tài)庆寺。
(2)蚊夫、可見進(jìn)程,比如主Activity上彈出一個對話框懦尝,該Activity的進(jìn)程狀態(tài)就為可見進(jìn)程知纷。
(3)、服務(wù)進(jìn)程陵霉,比如正在運行的Service的狀態(tài)琅轧。
(4)、后臺進(jìn)程踊挠,比如Activity乍桂,按Home鍵之后的狀態(tài)。
(5)、空進(jìn)程睹酌,該進(jìn)程狀態(tài)主要用來緩存進(jìn)程权谁,保存一些進(jìn)程的數(shù)據(jù),方便下次啟動的時候憋沿,直接從緩存讀取數(shù)據(jù)旺芽。
Application的生命周期:
(1)、onCreate在創(chuàng)建應(yīng)用程序時調(diào)用辐啄〔烧拢可以重寫這個方法來實現(xiàn)實例化應(yīng)用程序單態(tài),以及創(chuàng)建和實例化任何程序狀態(tài)變量和共享資源则披。
(2)共缕、onLowMemory當(dāng)系統(tǒng)處于資源匱乏的時候,具有良好行為的應(yīng)用程序可以釋放額外的內(nèi)存士复。這個方法一般只會在后臺進(jìn)程已經(jīng)終止图谷,但是前臺應(yīng)用程序仍然缺少內(nèi)存時調(diào)用≮搴椋可以重寫這個處理程序來清空緩存或釋放不必要的資源便贵。
(3)、onTrimMemory作為onLowMemory的一個特定于應(yīng)用程序的替代選擇冗荸,在Android4.0時引入承璃。當(dāng)運行時決定當(dāng)前應(yīng)用程序應(yīng)該嘗試減少其內(nèi)存開銷時調(diào)用,它包含一個level參數(shù)蚌本,用于提供請求的上下文盔粹。
(4)、onConfigurationChanged與Activity不同程癌,在配置改變時舷嗡,應(yīng)用程序?qū)ο蟛粫唤K止和重啟。如果應(yīng)用程序使用的值依賴于特定的配置嵌莉,則重寫這個方法來重新加載這些值进萄,或在應(yīng)用程序級別處理配置改變。
28锐峭、封裝View的時候怎么知道view的大小
getMeasuredHeight():獲取控件的實際高度中鼠,包括顯示的部分和超出屏幕的部分,它的值與屏幕無關(guān)沿癞。
getHeight():獲取控件在屏幕中顯示的高度援雇。
getMeasuredWidth():與getMeasuredHeight()類似。
getWidth():與getHeigth()類似椎扬。
29熊杨、RecycleView原理
RecycleView將onMeasure()曙旭,onLayout()交給了LayoutManager去處理,因此晶府,RecyclerView設(shè)置不同的LayoutManager就可以達(dá)到不同的顯示效果,因為onMeasure()和onLayout()不一樣钻趋。
ItemDecoration是為了顯示每個item之間分隔樣式的川陆。它本質(zhì)上就是一個Drawable。當(dāng)RecyclerView執(zhí)行到onDraw()蛮位,這時,如果重寫了該方法,就相當(dāng)于在RecyclerView上畫了一個Drawable表現(xiàn)的東西氧急。而最后拐叉,在它的內(nèi)部還有一個叫g(shù)etItemOffsets()的方法,從字面來理解萄焦,它是用來偏移每個item視圖的控轿,當(dāng)我們在每個item之間強(qiáng)行插入繪畫一段Drawable,那么如果再用原來的邏輯去繪制item視圖拂封,就會覆蓋掉Decoration茬射,所以需要這個方法將每個item向后偏移,以免覆蓋分隔樣式冒签。
ItemAnimation每個item在特定的情況下都會執(zhí)行的動畫在抛。說是特定情況,其實就是視圖在發(fā)生改變的時候萧恕,我們手動調(diào)用notifyXXX()方法的時候刚梭。通常這個時候,我們要傳一個下標(biāo)票唆,那么從這個下標(biāo)一直到最后朴读,所有的item都要執(zhí)行這個動畫。
Adapter首先是適配器惰说,適配器的作用都是類似的磨德,用于提供每個item視圖,并返回給RecyclerView作為其子布局添加到內(nèi)部吆视。但是典挑,與ListView不同的是,ListView的適配器是直接返回一個View啦吧,將這個View添加到ListView的內(nèi)部您觉。而RecyclerView是返回一個ViewHolder并且不是直接將這個holder添加到視圖內(nèi)部,而是添加到一個緩沖區(qū)授滓,在視圖需要的時候去緩沖區(qū)找到這個holder琳水,再間接找到holder包裹的View肆糕。
每個ViewHolder內(nèi)部都包裹著一個View,并且ViewHolder必須繼承自RecyclerView.ViewHolder類在孝。這主要是因為RecyclerView內(nèi)部的緩存結(jié)構(gòu)并不像ListView那樣緩存一個View诚啃,而是直接緩存一個ViewHolder,在ViewHolder內(nèi)部又持有一個View私沮。既然緩存的是ViewHolder始赎,那么當(dāng)然就所有的ViewHolder必須都繼承同一個類。
https://www.cnblogs.com/jiangbeixiaoqiao/p/5672766.html
30仔燕、AndroidManifest的作用與理解
作用:
(1)造垛、描述app的包名:Android設(shè)備據(jù)此區(qū)分不同的app,如果每個app是一個人的話晰搀,那么包名就是這個人的名字(為了防止惡意軟件仿冒其他app五辽,只有新的app包名和簽名均與就的app相同,才能升級)外恕。
(2)杆逗、描述app使用的Android版本信息。
(3)吁讨、描述app本身的版本信息髓迎,這樣對于app兩個版本,系統(tǒng)可以區(qū)分哪個是新版本建丧,哪個是舊版本排龄。
(4)、描述應(yīng)用對外暴露的組件(或者叫接口)翎朱。
(5)橄维、其他各種需要用文本直接告知系統(tǒng)的信息:包括權(quán)限,應(yīng)用主題等拴曲。
https://blog.csdn.net/wyzzgo/article/details/73556414
(三)常見的一些原理性問題
1争舞、Handler機(jī)制和底層實現(xiàn)
Handler包括四個角色:
Handler:負(fù)責(zé)發(fā)送消息處理消息。
Message:消息實體對象澈灼,handler通過sendMessage將實體放入消息隊列中竞川。
MessageQueue:存放消息的隊列。
Looper:消息輪詢器叁熔,不停地從消息隊列中取出消息交給handler處理委乌。
在主線程創(chuàng)建Handler,在需要發(fā)送消息的地方創(chuàng)建Message荣回,通過handler發(fā)送遭贸。這個消息回到MessageQueue中,然后Looper將這個消息取出交給handler處理心软。
Handler可以有多個壕吹,但是在同一線程中Looper和MessageQueue只有一個著蛙。
2、Handler耳贬、Thread和HandlerThread的差別
Thread:普通的異步線程踏堡。
Handler:異步更新UI的,更詳細(xì)的來說是用來做線程通信的效拭,更新UI時是子線程與UI主線程之間的通信暂吉。
HandlerThread:子線程與子線程之間的通信。它內(nèi)部創(chuàng)建一個帶有Looper的線程缎患,looper對象可以用于創(chuàng)建Handler類來進(jìn)行調(diào)度。
3阎肝、handler發(fā)消息給子線程挤渔,looper怎么啟動?
Looper.prepare()啟動Looper风题。
Looper.loop()停止Looper循環(huán)判导。
4、關(guān)于Handler沛硅,在任何地方new Handler 都是什么線程下?
默認(rèn)情況下眼刃,Android創(chuàng)建的線程沒有開啟消息循環(huán)Looper,主線程除外摇肌。
系統(tǒng)自動為主線程創(chuàng)建Looper對象擂红,開啟消息循環(huán);
所以主線程中可以直接new Handler围小,但在子線程中不能直接new昵骤,子線程中需要:
5、ThreadLocal原理肯适,實現(xiàn)及如何保證Local屬性变秦?
當(dāng)需要多線程時,有個變量恰巧不需要共享框舔,此時就不必使用Synchronized這么麻煩的關(guān)鍵字來鎖住蹦玫,每個線程都相當(dāng)于在堆內(nèi)開辟一個空間,線程中帶有對共享變量的緩沖區(qū)刘绣,通過緩沖區(qū)將內(nèi)存中的共享變量進(jìn)行讀取和操作樱溉,ThreadLocal相當(dāng)于線程中的內(nèi)存,一個局部變量额港。每次可以對線程自身的數(shù)據(jù)讀取和操作饺窿,并不需要通過緩沖區(qū)與主內(nèi)存中的變量進(jìn)行交互。并不會像synchronized那樣修改主內(nèi)存中的數(shù)據(jù)移斩,再將主內(nèi)存中的數(shù)據(jù)復(fù)制到線程內(nèi)的工作內(nèi)存肚医。ThreadLocal可以讓線程獨占資源绢馍,存儲于線程內(nèi)部,避免線程阻塞造成CPU吞吐下降肠套。
6舰涌、請解釋下在單線程模型中Message、Handler你稚、Message Queue瓷耙、Looper之間的關(guān)系
Handler獲取當(dāng)前線程中的looper對象,looper用來從存放Message的MessageQueue中取出Message刁赖,再由Handler進(jìn)行消息的分發(fā)和處理搁痛。
7、請描述一下View事件傳遞分發(fā)機(jī)制
事件分發(fā)需要View的三個重要方法共同完成:
(1)宇弛、dispatchTouchEvent(MotionEvent event)
返回值表示是否消費了當(dāng)前事件鸡典。可能View本身的onTouchEvent方法消費枪芒,也可能是子View的dispatchTouchEvent方法中消費彻况。返回true表示事件被消費,本次事件終止舅踪。返回false表示View以及子View都沒有消費事件纽甘,將調(diào)用父View的onTouchEvent方法。
(2)抽碌、onInterceptTouchEvent(MotionEvent event)
事件攔截悍赢,當(dāng)一個ViewGroup在接到MotionEvent事件序列的時候,首先會調(diào)用此方法判斷是否需要攔截咬展。特別注意泽裳,這是ViewGroup特有的方法,View并沒有攔截方法破婆。
返回值表示是否攔截事件傳遞涮总,返回true表示攔截了事件,那么事件將不再向下分發(fā)祷舀,而是調(diào)用View本身的onTouchEvent方法瀑梗。返回false表示不進(jìn)行攔截,事件向下分發(fā)到子View的dispatchTouchEvent方法裳扯。
(3)抛丽、onTouchEvent(MotionEvent event)
真正對MotionEvent進(jìn)行處理或消費的方法。在dispatchTouchEvent中調(diào)用饰豺。
返回值返回true表示事件被消費亿鲜,本次的事件終止;返回false表示事件并沒有被消費,將調(diào)用父View的onTouchEvent方法蒿柳。
8饶套、Touch事件傳遞流程
android的touch事件自上而下傳遞:經(jīng)過Activity->PhoneWindow->DectorView->ContentView->ViewGroup->ChildView
其中最主要的是Activity、ViewGroup和View的處理
9垒探、事件分發(fā)中的onTouch 和onTouchEvent 有什么區(qū)別妓蛮,又該如何使用?
onTouch方法優(yōu)先級高于onTouchEvent圾叼,會先觸發(fā)蛤克。假如onTouch方法返回false,會接著觸發(fā)onTouchEvent方法夷蚊,反之构挤,onTouchEvent方法并不會被調(diào)用。內(nèi)置諸如click事件的實現(xiàn)等都基于onTouchEvent方法惕鼓,假如onTouch方法返回true儿倒,這些事件將不會被觸發(fā)。
https://blog.csdn.net/qq_26358311/article/details/79620964
10呜笑、View和ViewGroup分別有哪些事件分發(fā)相關(guān)的回調(diào)方法
11、View刷新機(jī)制
View更新一共有兩個方法:invalidate和postInvalidate彻犁,其中前者是在UI線程中使用叫胁,而后者是在非UI線程中使用。
12汞幢、View繪制流程
View的measure過程
ViewGroup的measure過程
View的layout過程
ViewGroup的layout過程
View的draw過程
ViewGroup的draw過程
13驼鹅、自定義控件原理
View繪制的基本上是由measure(),layout()森篷,draw()三個方法完成的输钩。
https://blog.csdn.net/u012426327/article/details/77836069
14、自定義View如何提供獲取View屬性的接口仲智?
(1)买乃、在自定義View中定義一個接口。
(2)钓辆、類成員變量里聲明一個這個接口的引用剪验。
(3)、寫一個方法并持有Activity實現(xiàn)的接口的實例前联。
(4)功戚、在Activity里實現(xiàn)這個接口。
(5)似嗤、Activity里綁定XML中的自定義View屬性啸臀,并向XML創(chuàng)建的自定義View對象傳遞Activity實現(xiàn)的接口對象。
https://blog.csdn.net/hystudio_lzu/article/details/79135105
15烁落、Android代碼中實現(xiàn)WAP方式聯(lián)網(wǎng)
https://blog.csdn.net/asce1885/article/details/7844159
16乘粒、AsyncTask機(jī)制
AsyncTask是android提供的一種異步消息處理機(jī)制豌注,可以直接繼承AsyncTask,在類中繼承抽象方法執(zhí)行耗時任務(wù)谓厘,并且AsyncTask提供接口反饋當(dāng)前異步操作的進(jìn)度幌羞,可以通過接口實現(xiàn)UI更新。最終返回后臺執(zhí)行的結(jié)果給UI主線程竟稳,從而實現(xiàn)消息的異步處理属桦。
17、AsyncTask原理及不足
AsyncTask原理:
AsyncTask內(nèi)部是通過線程池+Handler實現(xiàn)他爸,構(gòu)造方法里邊new了兩個對象聂宾,在new WorkRunnable對象時通過result = doInBackground(mParams)給result賦值。然后調(diào)用postResult(result)方法诊笤,并把WorkRunnable對象當(dāng)做參數(shù)傳遞給FutureTask系谐。由于那是Runnable對象開啟線程跑任務(wù),跑完回調(diào)FutureTask的done()方法讨跟,這個方法又調(diào)用了postResultIfNotInvoked(get())方法纪他。
不足:
(1)、線程池中已有128個線程晾匠,緩沖隊列已滿茶袒,假設(shè)此時向線程提交任務(wù),將會拋出異常凉馆。
(2)薪寓、AsyncTask不會隨著Activity的銷毀而銷毀,直到doInBackground()方法運行完成澜共,假設(shè)我們的Activity銷毀之前沒有取消AsyncTask向叉,這有可能造成AsyncTask崩潰,因為有可能它要處理的View已經(jīng)被銷毀嗦董。
(3)母谎、假設(shè)AsyncTask被聲明為Activity的非靜態(tài)內(nèi)部類,那么AsyncTask會保留一個對創(chuàng)建了AsyncTask的Activity的引用展懈。
(4)销睁、屏幕旋轉(zhuǎn)或Activity在后臺被系統(tǒng)殺掉等情況會造成Activity再一次創(chuàng)建,之前運行的AsyncTask會持有銷毀之前的Activity的引用存崖,這個引用已經(jīng)無效冻记,這時調(diào)用onPostExecute()再去更新界面將不再生效。
https://www.cnblogs.com/lytwajue/p/7270299.html
18来惧、如何取消AsyncTask冗栗?
我們可以隨時調(diào)用cancel(boolean)去取消這個加載任務(wù),調(diào)這個方法會間接調(diào)用iscancelled并且返回true,調(diào)用cancel()后隅居,在doInBackground()return后钠至,我們將會調(diào)用onCancelled(Object)不再調(diào)用onPostExeecute(Object)方法,為了保證任務(wù)能夠更快的取消掉胎源,應(yīng)該在doInBackground()方法中周期性的檢查isCancelled去判斷棉钧。
19、為什么不能在子線程更新UI涕蚤?
Android的UI訪問是沒有加鎖的宪卿,多線程可以同時訪問更新操作同一個UI控件。也就是說訪問UI的時候万栅,android系統(tǒng)中的控件都不是線程安全的佑钾,這將導(dǎo)致在多線程模式下,當(dāng)多個線程共同訪問更新操作同一個控件時容易發(fā)生不可控的錯誤烦粒,而這是致命的休溶。所以Android中規(guī)定只能在UI線程中更新UI,這相當(dāng)于從另一個角度給Android的UI訪問加了鎖扰她,偽鎖兽掰。
20、ANR產(chǎn)生的原因是什么徒役?
(1)禾进、主線程執(zhí)行了耗時操作,比如數(shù)據(jù)操作或網(wǎng)絡(luò)請求廉涕。
(2)、其他進(jìn)程占用CPU導(dǎo)致本進(jìn)程得不到CPU時間片艇拍,比如其他進(jìn)程的頻繁讀寫操作可能會導(dǎo)致這個問題狐蜕。
21、ANR定位和修正
可以查看data/anr/traces.txt查看ANR信息卸夕。
根本原因就是主線程被卡层释,導(dǎo)致應(yīng)用在5秒內(nèi)未響應(yīng)用戶的輸入事件。
修正:
將耗時操作改到子線程中執(zhí)行快集。
22贡羔、oom是什么?
oom指的是Out Of Memory个初,內(nèi)存溢出乖寒。
23、什么情況導(dǎo)致oom院溺?
OOM可能的原因:
(1)楣嘁、數(shù)據(jù)庫的cursor沒有及時關(guān)閉
(2)、構(gòu)造Adapter沒有使用緩存convertView
(3)、RegisterReceiver()和unRegisterReceiver()沒有成對出現(xiàn)
(4)逐虚、未關(guān)閉InputStream聋溜、OutputStream
(5)、Bitmap使用后未調(diào)用recycle()
(6)叭爱、static等關(guān)鍵字
(7)撮躁、非靜態(tài)內(nèi)部類持有外部類的引用,context泄漏
24买雾、有什么解決方法可以避免OOM把曼?
(1)、針對數(shù)據(jù)庫cursor沒有關(guān)閉的情況凝果,如果查詢數(shù)據(jù)量少是不會造成內(nèi)存溢出的祝迂,但是數(shù)據(jù)量太大容易造成OOM,所以用完Cursor后應(yīng)該手動調(diào)用close方法關(guān)閉cursor器净。
(2)型雳、針對adapter沒有復(fù)用convertView的情況,除了要在getView方法里邊對convertView進(jìn)行判斷后復(fù)用山害,還應(yīng)該使用ViewHolder類來保存通過findViewById獲取的子控件地址值纠俭。
(3)、在Activity中注冊了廣播浪慌,但在Activity退出時沒有取消注冊的話可能會造成內(nèi)存溢出冤荆,需要手動在相應(yīng)的位置進(jìn)行反注冊。
(4)权纤、不關(guān)閉輸入輸出流的話就相當(dāng)于在內(nèi)存和硬盤一直存在著連接占用著資源钓简,當(dāng)其他操作需要資源時,就會造成內(nèi)存溢出汹想。
(5)外邓、位圖在Android中占用的內(nèi)存是很大的,使用后如不及時回收的話會占用大量空間古掏,所以針對位圖一般有以下幾種處理:
及時的調(diào)用recycle方法來手動回收损话;
設(shè)置采樣率,有時候我們不需要把圖片完全顯示出來槽唾,這時候就要按照比例來進(jìn)行縮放丧枪,在我們得到采樣率后就可以將圖片縮小后再進(jìn)行加載,節(jié)省大量內(nèi)存庞萍;
使用軟引用
(6)拧烦、應(yīng)該盡量避免static成員變量引用資源耗費過多實例,比如Context
Context盡量使用Application Context钝计,因為Application Context生命周期比較長屎篱,引用它不會出現(xiàn)內(nèi)存泄漏的問題
使用WeakReference代替強(qiáng)引用服赎。
(7)、非靜態(tài)內(nèi)部類交播,上下文泄漏重虑。
25、Oom 是否可以try catch秦士?為什么缺厉?
一般不適合這樣處理。
java內(nèi)存中除了顯式地catch OOM之外還有更多有效的方式隧土,比如SoftReference提针,WeakReference,硬盤緩存等曹傀。
如果OOM的原因不是在try中的代碼辐脖,那么catch依然會拋出OOM的異常。
26皆愉、內(nèi)存泄漏是什么嗜价?
內(nèi)存泄漏是指當(dāng)前程序不再使用到的內(nèi)存時,釋放內(nèi)存失敗而產(chǎn)生了無用的內(nèi)存消耗幕庐。內(nèi)存泄漏并不是指物理上的內(nèi)存消失久锥,這里的內(nèi)存泄漏是指由程序分配的內(nèi)存但是由于程序邏輯的錯誤而導(dǎo)致程序?qū)υ搩?nèi)存失去控制,使得內(nèi)存浪費异剥。
27瑟由、什么情況導(dǎo)致內(nèi)存泄漏?
(1)冤寿、資源對象沒有關(guān)閉導(dǎo)致內(nèi)存泄漏歹苦,如查詢數(shù)據(jù)庫沒有關(guān)閉cursor。
(2)督怜、構(gòu)造adapter時暂氯,沒有使用convertView復(fù)用。
(3)亮蛔、Bitmap對象不再使用時,未調(diào)用recycle()釋放內(nèi)存擎厢。
(4)究流、對象被生命周期長的對象引用,如Activity被靜態(tài)集合引用導(dǎo)致Activity不能釋放动遭。
28芬探、如何防止線程的內(nèi)存泄漏?
將AsyncTask或Runnable類獨立出來或使用靜態(tài)內(nèi)部類厘惦,這樣可以避免內(nèi)存泄漏偷仿。
29哩簿、內(nèi)存泄露場的解決方法
(1)、在涉及使用Context時酝静,優(yōu)先考慮Application Context节榜。
(2)、對于需要在靜態(tài)內(nèi)部類中使用非靜態(tài)外部成員變量(如:Context别智、View)宗苍,可以在靜態(tài)內(nèi)部類中使用弱引用來引用外部類的變量來避免內(nèi)存泄漏。
(3)薄榛、對于不再需要使用的對象讳窟,顯示的將其賦值為null,比如使用完Bitmap后先調(diào)用recycle()敞恋,再賦值為null.
(4)丽啡、保持對對象生命周期的敏感,特別注意單例硬猫、靜態(tài)對象补箍、全局性集合等的生命周期。
(5)浦徊、對于生命周期比Activity長的內(nèi)部類對象馏予,并且內(nèi)部類中使用了外部類的成員變量,可以這樣做避免內(nèi)存泄漏:將內(nèi)部類改為靜態(tài)內(nèi)部類盔性;靜態(tài)內(nèi)部類中使用弱引用來引用外部類的成員變量霞丧。
30、內(nèi)存泄漏和內(nèi)存溢出區(qū)別冕香?
內(nèi)存泄漏的堆積就會導(dǎo)致內(nèi)存溢出蛹尝。
內(nèi)存泄漏是指申請內(nèi)存后無法釋放已申請的內(nèi)存空間,內(nèi)存溢出是沒有足夠的內(nèi)存供申請者使用悉尾。
31突那、LruCache默認(rèn)緩存大小
手機(jī)內(nèi)存的1/8
32、ContentProvider的權(quán)限管理(解答:讀寫分離构眯,權(quán)限控制-精確到表級愕难,URL控制)
33、如何通過廣播攔截和abort一條短信惫霸?
https://blog.csdn.net/ljw124213/article/details/50492449
34猫缭、廣播是否可以請求網(wǎng)絡(luò)?
子線程可以壹店,主線程超過10s引起anr
35猜丹、廣播引起anr的時間限制是多少?
10s
36硅卢、計算一個view的嵌套層級
view.getParent()遞歸就可以就算嵌套層級射窒。
37藏杖、Activity棧
Activity棧記錄Activity的打開順序,先進(jìn)后出脉顿。
38蝌麸、Android線程有沒有上限拣播?
其實這個是沒有上限的馁痴,因為資源都是限制在這個進(jìn)程中,無論開多少線程都是這么多的資源培廓。至于開多少汉柒,完全取決于自己误褪,合理開線程,不卡就行碾褂。
39兽间、線程池有沒有上限?
有正塌,跟內(nèi)存掛鉤嘀略。
40、ListView重用的是什么乓诽?
ListView重用的是View
41帜羊、Android為什么引入Parcelable?
在內(nèi)存使用上Parcelable比Serializable性能高鸠天。
42讼育、有沒有嘗試簡化Parcelable的使用?
as插件簡化Parcelable使用稠集。
(四)開發(fā)中常見的一些問題
1奶段、ListView 中圖片錯位的問題是如何產(chǎn)生的?
如果只是簡單的展示list中的數(shù)據(jù),而沒用convertView的復(fù)用機(jī)制和異步操作剥纷,就不會產(chǎn)生圖片錯位的問題痹籍;重用但沒有異步,也不會出現(xiàn)這個問題晦鞋,但程序會很卡蹲缠。
圖片錯位就是因為convertView復(fù)用,同時異步加載圖片造成的悠垛。
2线定、混合開發(fā)有了解嗎?
混合開發(fā)的APP就是在app內(nèi)部內(nèi)嵌一個輕量級的瀏覽器鼎文,一部分原生的功能改為HTML5開發(fā),這部分功能不僅能夠在app不升級的情況下動態(tài)更新因俐,且可以在Android和IOS上運行拇惋,讓用戶體驗更好又可以節(jié)省開發(fā)的資源周偎。
3、知道哪些混合開發(fā)的方式撑帖?說出它們的優(yōu)缺點和各自使用場景蓉坎?(解答:比如:RN,weex胡嘿,H5蛉艾,小程序,WPA等衷敌。做Android的了解一些前端js等還是很有好處的)勿侯;
4、屏幕適配的處理技巧都有哪些?
布局盡量使用相對布局與線性布局
根據(jù)不同的分辨率的手機(jī)缴罗,提供不同的資源
限制橫豎屏切換助琐。
5、服務(wù)器只提供數(shù)據(jù)接收接口面氓,在多線程或多進(jìn)程條件下兵钮,如何保證數(shù)據(jù)的有序到達(dá)?
(1)舌界、有序掘譬,多線程需要使用同步,多線程要使用進(jìn)程通信保障數(shù)據(jù)傳輸?shù)捻樞颉?/p>
(2)呻拌、到達(dá)葱轩,使用TCP可靠傳輸,服務(wù)器返回傳輸成功后才能傳輸下一個柏锄。
(3)酿箭、要在傳輸包中加入順序標(biāo)識。
6趾娃、動態(tài)布局的理解
動態(tài)加載布局有三種方式
第一種方式內(nèi)部調(diào)用的是第二種方式缭嫡,第二種方式內(nèi)部調(diào)用的是第三種方式。
第三種方式分析:
參數(shù)一:要加載的布局文件抬闷。
參數(shù)二:父布局容器妇蛀。
參數(shù)三:false表示不把布局文件添加到容器中,true表示把布局文件添加到容器中笤成。
如果參數(shù)三設(shè)置了false评架,但添加了下面的代碼,表示和true一樣炕泳,都可以把布局添加到容器中纵诞。
7、怎么去除重復(fù)代碼培遵?
(1)浙芙、對于Activity或者Fragment登刺,抽取基類BaseActivity,BaseFragment嗡呼,在基類中抽取一些所有子類都需要的方法纸俭,比如:initView、initListener南窗、initData揍很、initStatusBarColors、startActivity万伤、showToast窒悔、checkNetConnected等方法。
(2)壕翩、對于xml布局文件蛉迹,在多個頁面中同時出現(xiàn)的、可以重復(fù)利用的放妈,就單獨抽出來北救,用include引入,比如:標(biāo)題欄芜抒,下一步按鈕珍策,等等一些可以抽取出來的公共部分。
(3)宅倒、對于資源文件的引用攘宙,比如文字的text、文字大小textSize拐迁、文字顏色textColor蹭劈,全部采用引用,不要全部寫死到布局中线召,對于文字text一律寫到string中铺韧、對于文字大小,一律寫入dimens中缓淹,對于文字顏色哈打,一律寫入到color中,然后統(tǒng)一引入xml布局文件中讯壶。
8料仗、畫出 Android 的大體架構(gòu)圖
9、Recycleview和ListView的區(qū)別
(1)伏蚊、ViewHolder是用來保存視圖引用的類立轧,無論是ListView還是RecyclerView。
在ListView中,ViewHolder需要自定義氛改,使用ViewHolder的時候匀借,每次getView時,都會調(diào)用findViewById平窘,所以會造成卡頓。
RecyclerView使用RecyclerView.ViewHolder凳怨,解決了ListView的卡頓問題
(2)瑰艘、ListView只能在垂直方向滑動
RecyclerView可以水平和豎直方向滑動
可以布局交叉網(wǎng)格風(fēng)格的列表,如瀑布流
支持網(wǎng)格風(fēng)格的列表肤舞。
(3)紫新、RecyclerView增加了View動畫
(4)、ListView通過AdapterView.OnItemClickListener接口來探測點擊事件李剖。
RecyclerView則通過RecyclerView.OnItemTouchListener接口來探測觸摸事件芒率。
https://blog.csdn.net/kimi985566/article/details/79839692
10、ListView圖片加載錯亂的原理和解決方案
ListView圖片加載錯亂是因為異步請求和convertView復(fù)用造成的篙顺。
解決方案:
對imageView設(shè)置tag偶芍,并預(yù)設(shè)一張圖片。
11德玫、動態(tài)權(quán)限適配方案匪蟀,權(quán)限組的概念
對于低于M版本的Android系統(tǒng),沒有動態(tài)權(quán)限的申請問題宰僧,動態(tài)權(quán)限的申請流程對于低于M版本的android系統(tǒng)也不再適用材彪。所以適配方案,首先要考慮低于M版本的Android系統(tǒng)琴儿,因此對于低于M版本的Android系統(tǒng)段化,在檢查權(quán)限時,直接返回true造成;對于高于M版本的系統(tǒng)显熏,可以將動態(tài)權(quán)限申請進(jìn)行一次封裝。
12谜疤、Android系統(tǒng)為什么會設(shè)計ContentProvider佃延?
Android設(shè)計ContentProvider主要是為了實現(xiàn)跨進(jìn)程通信。
為了應(yīng)用程序之間交換數(shù)據(jù)夷磕,Android提供了ContentProvider履肃,ContentProvider是不同應(yīng)用程序之間進(jìn)行數(shù)據(jù)交換的標(biāo)準(zhǔn)API,當(dāng)一個應(yīng)用程序需要把自己的數(shù)據(jù)暴露給其他應(yīng)用程序使用時坐桩,該應(yīng)用程序就可以通過提供ContentProvider來實現(xiàn)尺棋,其他應(yīng)用程序就可以通過ContentProvider來操作ContentProvider暴露出來的數(shù)據(jù)。
13、下拉狀態(tài)欄是不是影響activity的生命周期
不會影響Activity的生命周期膘螟。
14成福、如果在onStop的時候做了網(wǎng)絡(luò)請求,onResume的時候怎么恢復(fù)荆残?
stop的時候被暫停奴艾,onStart的時候重新檢測恢復(fù)請求即可。
如果是恢復(fù)頁面請求后的頁面數(shù)據(jù)内斯,分兩種蕴潦,一、Activity已經(jīng)銷毀俘闯,那么使用saveInstanceState存儲數(shù)據(jù)潭苞,onRestoreInstanceState()恢復(fù)數(shù)據(jù);二真朗,Activity沒有銷毀此疹,那就不需要恢復(fù)。
15遮婶、Bitmap 使用時候注意什么蝗碎?
(1)、要使用合適的圖片規(guī)格(bitmap類型)
(2)旗扑、降低采樣率
(3)衍菱、復(fù)用內(nèi)存。
(4)肩豁、及時回收
(5)脊串、壓縮圖片
(6)、盡量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource來設(shè)置一張大圖清钥,因為這些函數(shù)在完成decode后琼锋,最終都會通過java層調(diào)用createBitmap來完成,需要消耗更多的內(nèi)存祟昭,可以通過BitmapFactory.decodeStream方法缕坎,創(chuàng)建出一個Bitmap,再將其設(shè)置成ImageView的source篡悟。
http://www.reibang.com/p/fbf5a310788c
16谜叹、Bitmap的recycler()
Android有自己的垃圾回收機(jī)制,如果只使用了少量的圖片搬葬,回收與否關(guān)系不大荷腊。可是若有大量的bitmap需要垃圾回收急凰,那么垃圾回收的次數(shù)過于頻繁女仰,會造成系統(tǒng)資源負(fù)荷。所以還是自己recycler()比較好。
一定要注意ImageView的圖片來源疾忍,然后進(jìn)行相應(yīng)的recycler
17乔外、Android中開啟攝像頭的主要步驟
一共有兩種方式可以使用Android中的攝像頭
(1)、調(diào)用Android系統(tǒng)現(xiàn)有的攝像頭程序一罩。
(2)杨幼、直接使用Android系統(tǒng)提供的攝像頭API。
啟動安裝在手機(jī)上的攝像頭應(yīng)用程序聂渊。
使用靜態(tài)方法通過Camera.open()方法初始化相機(jī)對象推汽。
18、ViewPager使用細(xì)節(jié)歧沪,如何設(shè)置成每次只初始化當(dāng)前的Fragment,其他的不初始化莲组?
每次只初始化一個頁面的時候诊胞,就要注意了,需要采用懶加載的方式锹杈,因為在頁面進(jìn)入前臺的時候撵孤,是會調(diào)用setUserVisiableHint()這個方法的,通過這個方法竭望,我們可以獲得當(dāng)前頁面是否對用戶可見邪码,并在對用戶可見的時候進(jìn)行初始化,這時還需要注意一點咬清,setUserVisiableHint()這個方法的調(diào)用并不保證View等需要的東西是否已經(jīng)初始化成功闭专,所以還需要再判斷一下。
19旧烧、點擊事件被攔截影钉,但是想傳到下面的View,如何操作掘剪?
在父控件中加入請求父控件不攔截子控件的觸摸事件平委,自定義重寫子控件的dispatchTouchView();
就可以阻止父控件對子控件點擊事件的攔截,可以為子控件單獨設(shè)置點擊事件的響應(yīng)夺谁。
20廉赔、微信主頁面的實現(xiàn)方式
fragment嵌套。
21匾鸥、微信上消息小紅點的原理
可以是UI設(shè)計是切出的帶有小紅點的圖蜡塌,也可以自定義RadioButton繪制小紅點。
22勿负、CAS介紹(這是阿里巴巴的面試題岗照,我不是很了解,可以參考博客: CAS簡介)
(1)、訪問服務(wù):SSO客戶端發(fā)送請求訪問應(yīng)用系統(tǒng)提供的服務(wù)資源攒至。
(2)厚者、重定向認(rèn)證:SSO客戶端會重定向用戶請求到SSO服務(wù)器
(3)、用戶驗證:驗證用戶身份
(4)迫吐、生成票據(jù):SSO服務(wù)器會產(chǎn)生一個隨機(jī)的Service Ticket
(5)库菲、驗證票據(jù):SSO服務(wù)器驗證票據(jù)Service Ticket的合法性,驗證通過后志膀,允許客戶端訪問服務(wù)熙宇。
(6)、傳輸用戶信息:SSO服務(wù)器驗證票據(jù)通過后溉浙,傳輸用戶認(rèn)證結(jié)果信息給客戶端烫止。
附;AndroidAPP開發(fā)框架技術(shù)體系大綱戳稽;