天天看點

2020上半年百度Android崗(初級到進階)面試真題全收錄 解析

1、oncreate() 中不執行耗時操作 把頁面顯示的 view 細分一下,放在 asynctask 裡逐漸顯示,用 handler 更好。這樣使用者的看到的就是有層次有步驟的一個個的 view 的展示,不會是先看到一個黑屏,然後一下顯示所有 view。最好做成動畫,效果更自然。 2、利用多線程的目的就是盡可能的減少 oncreate() 和 onreume() 的時間,使得使用者能盡快看到頁面,操作頁面。 3、減少主線程阻塞時間。 4、提高 adapter 和 adapterview 的效率。 5、優化布局檔案。

3.5、直接在activity中建立一個thread跟在service中建立一個thread之間的差別?

在activity中被建立:該thread的就是為這個activity服務的,完成這個特定的activity交代的任務,主動通知該activity一些消息和事件,activity銷毀後,該thread也沒有存活的意義了。 在service中被建立:這是保證最長生命周期的thread的唯一方式,隻要整個service不退出,thread就可以一直在背景執行,一般在service的oncreate()中建立,在ondestroy()中銷毀。是以,在service中建立的thread,适合長期執行一些獨立于app的背景任務,比較常見的就是:在service中保持與伺服器端的長連接配接。

3.6、activity 與 service 通信的四種方式

1、binder 2、intent 3、接口 interface 4、broadcast 廣播接收

3.7、activity 之間的幾種通信方式

1、intent 2、借助類的靜态變量 3、借助全局變量/application 4、借助外部工具 5、 借助 sharedpreference 6、使用 android 資料庫 sqlite 7、 赤裸裸的使用 file 8、android 剪切闆 9、借助 service

4.1、服務啟動一般有幾種,服務和activty之間怎麼通信,服務和服務之間怎麼通信

方式: 1、startservice: oncreate()--->onstartcommand() ---> ondestory() 如果服務已經開啟,不會重複的執行oncreate(), 而是會調用onstartcommand()。一旦服務開啟跟調用者(開啟者)就沒有任何關系了。 開啟者退出了,開啟者挂了,服務還在背景長期的運作。 開啟者不能調用服務裡面的方法。 2、bindservice: oncreate() --->onbind()--->onunbind()--->ondestory() bind的方式開啟服務,綁定服務,調用者挂了,服務也會跟着挂掉。 綁定者可以調用服務裡面的方法。 通信: 1、通過binder對象。 2、通過broadcast(廣播)。

4.2、如何保證service不被殺死?

android 程序不死從3個層面入手: a.提供程序優先級,降低程序被殺死的機率 方法一:監控手機鎖屏解鎖事件,在螢幕鎖屏時啟動1個像素的 activity,在使用者解鎖時将 activity 銷毀掉。 方法二:啟動前台service。 方法三:提升service優先級: 在androidmanifest.xml檔案中對于intent-filter可以通過android:priority = "1000"這個屬性設定最高優先級,1000是最高值,如果數字越小則優先級越低,同時适用于廣播。 b. 在程序被殺死後,進行拉活 方法一:注冊高頻率廣播接收器,喚起程序。如網絡變化,解鎖螢幕,開機等 方法二:雙程序互相喚起。 方法三:依靠系統喚起。 方法四:ondestroy方法裡重新開機service:service + broadcast 方式,就是當service走ondestory的時候,發送一個自定義的廣播,當收到廣播的時候,重新啟動service; c. 依靠第三方 根據終端不同,在小米手機(包括 miui)接入小米推送、華為手機接入華為推送;其他手機可以考慮接入騰訊信鴿或極光推送與小米推送做 a/b test。

5.1、廣播注冊一般有幾種,各有什麼優缺點?

第一種是常駐型(靜态注冊):當應用程式關閉後如果有資訊廣播來,程式也會被系統調用,自己運作。 第二種不常駐(動态注冊):廣播會跟随程式的生命周期。 動态注冊 優點: 在android的廣播機制中,動态注冊優先級高于靜态注冊優先級,是以在必要情況下,是需要動态注冊廣播接收者的。 缺點: 當用來注冊的 activity 關掉後,廣播也就失效了。 靜态注冊 優點: 無需擔憂廣播接收器是否被關閉,隻要裝置是開啟狀态,廣播接收器就是打開着的。

6.1、activty和fragmengt之間怎麼通信,fragmengt和fragmengt怎麼通信?

(一)handler (二)廣播 (三)事件總線:eventbus、rxbus、otto (四)接口回調 (五)bundle和setarguments(bundle)

7.1、自定義view效率高于xml定義嗎?說明理由。

自定義view效率高于xml定義: 1、少了解析xml。 2.、自定義view 減少了viewgroup與view之間的測量,包括父量子,子量自身,子在父中位置擺放,當子view變化時,父的某些屬性都會跟着變化。

7.2、listview卡頓原因

adapter的getview方法裡面convertview沒有使用settag和gettag方式; 在getview方法裡面viewholder初始化後的指派或者是多個控件的顯示狀态和背景的顯示沒有優化好,抑或是裡面含有複雜的計算和耗時操作; 在getview方法裡面 inflate的row 嵌套太深(布局過于複雜)或者是布局裡面有大圖檔或者背景所緻; adapter多餘或者不合理的notifysetdatachanged; listview 被多層嵌套,多次的onmessure導緻卡頓,如果多層嵌套無法避免,建議把listview的高和寬設定為match_parent. 如果是代碼繼承的listview,那麼也請你别忘記為你的繼承類添加上layoutprams,注意高和寬都mactch_parent的;

7.3、linearlayout、framelayout、relativelayout性能對比,為什麼?

relativelayout會讓子view調用2次onmeasure,linearlayout 在有weight時,也會調用子 view 2次onmeasure relativelayout的子view如果高度和relativelayout不同,則會引發效率問題,當子view很複雜時,這個問題會更加嚴重。如果可以,盡量使用padding代替margin。 在不影響層級深度的情況下,使用linearlayout和framelayout而不是relativelayout。
2020上半年百度Android崗(初級到進階)面試真題全收錄 解析

8.1bunder傳遞對象為什麼需要序列化?serialzable和parcelable的差別?

因為bundle傳遞資料時隻支援基本資料類型,是以在傳遞對象時需要序列化轉換成可存儲或可傳輸的本質狀态(位元組流)。序列化後的對象可以在網絡、ipc(比如啟動另一個程序的activity、service和reciver)之間進行傳輸,也可以存儲

到本地。

serializable(java自帶):

serializable 是序列化的意思,表示将一個對象轉換成存儲或可傳輸的狀态。序列化後的對象可以在網絡上進傳輸,也可以存儲到本地。

parcelable(android專用):

除了serializable之外,使用parcelable也可以實作相同的效果,不過不同于将對象進行序列化,parcelable方式的實作原理是将一個完整的對象進行分解,而分解後的每一部分都是intent所支援的資料類型,這也就實作傳遞對象的功能了。

8.2、android中有哪幾種解析xml的類,官方推薦哪種?以及它們的原理和差別?

dom解析 優點: 1.xml樹在記憶體中完整存儲,是以可以直接修改其資料結構. 2.可以通過該解析器随時通路xml樹中的任何一個節點. 3.dom解析器的api在使用上也相對比較簡單. 缺點: 如果xml文檔體積比較大時,将文檔讀入記憶體是非消耗系統資源的. 使用場景: dom 是與平台和語言無關的方式表示 xml文檔的官方 w3c 标準. dom 是以層次結構組織的節點的集合.這個層次結構允許開人員在樹中尋找特定資訊.分析該結構通常需要加載整個文檔和構造層次結構,然後才能進行任何工作. dom 是基于對象層次結構的. sax解析 sax 對記憶體的要求比較低,因為它讓開發人員自己來決定所要處理的标簽.特别是當開發人員隻需要處理文檔中包含的部分資料時,sax 這種擴充能力得到了更好的展現. 用sax方式進行xml解析時,需要順序執行,是以很難通路同一文檔中的不同資料.此外,在基于該方式的解析編碼程式也相對複雜. 對于含有資料量十分巨大,而又不用對文檔的所有資料行周遊或者分析的時候,使用該方法十分有效.該方法不将整個文檔讀入記憶體,而隻需讀取到程式所需的文檔标記處即可. xmlpull解析 android sdk提供了xmlpullapi,xmlpull和sax類似,是基于流(stream)操作檔案,後者根據節點事件回調開發者編寫的處理程式.因為是基于流的處理,是以xmlpull和sax都比較節約記憶體資源,不會像dom那樣要把所有節點以對象樹的形式展現在記憶體中.xmpull比sax更簡明,而且不需要掃描完整個流.

9.1、android中程序的優先級?

1.前台程序: 即與使用者正在互動的activity或者activity用到的service等,如果系統記憶體不足時前台程序是最晚被殺死的 2.可見程序: 可以是處于暫停狀态(onpause)的activity或者綁定在其上的service,即被使用者可見,但由于失了焦點而不能與使用者互動 3.服務程序: 其中運作着使用startservice方法啟動的service,雖然不被使用者可見,但是卻是使用者關心的,例如使用者正在非音樂界面聽的音樂或者正在非下載下傳頁面下載下傳的檔案等;當系統要空間運作,前兩者程序才會被終止 4.背景程序: 其中運作着執行onstop方法而停止的程式,但是卻不是使用者目前關心的,例如背景挂着的qq,這時的程序系統一旦沒了有記憶體就首先被殺死 5.空程序: 不包含任何應用程式的程序,這樣的程序系統是一般不會讓他存在的

9.2、android中跨程序通訊的幾種方式

1:通路其他應用程式的activity 如調用系統通話應用 2:content provider 如通路系統相冊 3:廣播(broadcast) 如顯示系統時間 4:aidl服務

9.3、為什麼要用多程序?有哪些方式?怎麼使用多程序

我們都知道,android 平台對應用都有記憶體限制,其實這個了解有點問題,應該是說 android 平台對每個程序有記憶體限制,比如某機型對對程序限制是 24m,如果應用有兩個程序,則該 應該的總記憶體限制是 2*24m。使用多程序就可以使得我們一個 apk 所使用的記憶體限制加大 幾倍。是以可以借此圖檔平台對應用的記憶體限制,比如一些要對圖檔、視訊、大檔案程序處理的好 記憶體的應用可以考慮用多程序來解決應用操作不流暢問題。 開啟多程序模式: 在 android 中 使 用多 程序 隻 有 一 種方 法,那 就是 在 androidmanifest 中 給 四 大 元件(activity,service,receiver,contentprovider)指定 android:process 屬性.除此之外沒有其他的辦法,也就是說我們無法給一個線程活一個實體類指定其運作時所在的程序.其實還有另一種非正常的多程序方法,那就是通過 jni 在 native 層去 fork 一個新的程序,但這種方法屬于特殊情況,并不是常用的建立多程序的方式,是以我們也暫不考慮這種情況程序名以":"開頭的程序屬于目前應用的私有程序,其他應用的元件不可以和它跑在同一個程序中,而程序名不以":"開頭的程序屬于全局程序,其他應用通過 shareuid 方式可以和它跑在同一個程序中.用多程序的好處與壞處 好處 1)分擔主程序的記憶體壓力。 當應用越做越大,記憶體越來越多,将一些獨立的元件放到不同的程序,它就不占用主程序的 記憶體空間了。當然還有其他好處,有心人會發現 2)使應用常駐背景,防止主程序被殺守護程序,守護程序和主程序之間互相監視,有一方 被殺就重新啟動它。android 背景程序裡有很多應用是多個程序的,因為它們要常駐背景,特别是即時通訊或者社交應用,不過現在多程序已經被用爛了。 典型用法是在啟動一個不可見的輕量級私有程序,在背景收發消息,或者做一些耗時的事情, 或者開機啟動這個程序,然後做監聽等。 壞處:消耗使用者的電量。 多占用了系統的空間,若所有應用都這樣占用,系統記憶體很容易占滿而導緻卡頓。 應用程式架構會變得複雜,因為要處理多程序之間的通信。這裡又是另外一個問題了。 多程序的缺陷程序間的記憶體空間是不可見的。開啟多程序後,會引發以下問題: 1)application 的多次重建。 2)靜态成員的失效。 3)檔案共享問題。 4)斷點調試問題。

10.1、android5.0新特性

1.materialdesign設計風格 2.支援64位art虛拟機(5.0推出的art虛拟機,在5.0之前都是dalvik。他們的差別是: dalvik,每次運作,位元組碼都需要通過即時編譯器轉換成機器碼(jit)。 art,第一次安裝應用的時候,位元組碼就會預先編譯成機器碼(aot)) 3.通知詳情可以使用者自己設計

10.2、android6.0新特性

1.動态權限管理 2.支援快速充電的切換 3.支援檔案夾拖拽應用 4.相機新增專業模式

10.3、android7.0新特性

1.多視窗支援 2.v2簽名 3.增強的java8語言模式 4.夜間模式

10.4、android8.0(o)新特性

1.通知管道 (notification channel) 通知标志 休眠 通知逾時 通知設定 通知清除 2.畫中畫模式:清單中activity設定android:supportspictureinpicture 3.背景限制 4.自動填充架構 5.系統優化 6.等等優化很多

10.5、android9.0(p)新特性

1.室内wifi定位 2.“劉海”螢幕支援 3.安全增強

10.6、android10.0新特性

夜間模式:包括手機上的所有應用都可以為其設定暗黑模式。 桌面模式:提供類似于pc的體驗,但是遠遠不能代替pc。 螢幕錄制:通過長按“電源”菜單中的"螢幕快照"來開啟。

11.1、bitmap 使用時候注意什麼?

1、要選擇合适的圖檔規格(bitmap類型) 2、降低采樣率。bitmapfactory.options 參數insamplesize的使用,先把options.injustdecodebounds設為true,隻是去讀取圖檔的大小,在拿到圖檔的大小之後和要顯示的大小做比較通過calculateinsamplesize()函數計算insamplesize的具體值,得到值之後。options.injustdecodebounds設為false讀圖檔資源。 3、複用記憶體。即,通過軟引用(記憶體不夠的時候才會回收掉),複用記憶體塊,不需要再重新給這個bitmap申請一塊新的記憶體,避免了一次記憶體的配置設定和回收,進而改善了運作效率。 4、使用recycle()方法及時回收記憶體。 5、壓縮圖檔。

11.2、如何計算一個bitmap占用記憶體的大小,怎麼保證加載bitmap不産生記憶體溢出?

在bitmap裡有兩個擷取記憶體占用大小的方法。 (1)getbytecount():api12 加入,代表存儲 bitmap 的像素需要的最少記憶體。 getallocationbytecount():api19 加入,代表在記憶體中為 bitmap 配置設定的記憶體大小,代替了 getbytecount() 方法。 在不複用 bitmap 時,getbytecount() 和 getallocationbytecount 傳回的結果是一樣的。在通過複用 bitmap 來解碼圖檔時,那麼 getbytecount() 表示新解碼圖檔占用記憶體的大 小,getallocationbytecount() 表示被複用 bitmap 真實占用的記憶體大小(即 mbuffer 的長度)。 (2)bitmapfactory.options.inpreferredconfig:将argb_8888改為rgb_565,改變編碼方式,節約記憶體。 bitmapfactory.options.insamplesize:縮放比例,可以參考luban那個庫,根據圖檔寬高計算出合适的縮放比例。 bitmapfactory.options.inpurgeable:讓系統可以記憶體不足時回收記憶體。

11.3、一張圖檔加載到手機記憶體中真正的大小是怎麼計算的

activity.runonuithread(runnable) view.post(runnable),view.postdelay(runnable, long)(可以了解為在目前操作視圖ui線程添加隊列) handler asynctask rxjava livedata
在android上,如果你的應用程式有一段時間響應不夠靈敏,系統會向使用者顯示一個對話框,這個對話框稱作應用程式無響應(anr:application notresponding)對話框。使用者可以選擇讓程式繼續運作,但是,他們在使用你的應用程式時,并不希望每次都要處理這個對話框。是以,在程式裡對響應性能的設計很重要這樣,這樣系統就不會顯示anr給使用者。
asynctask是什麼? asynctask是一種輕量級的異步任務類,它可以線上程池中執行背景任務,然後把執行的進度和最終結果傳遞給主線程并在主線程中更新ui。 asynctask是一個抽象的泛型類,它提供了params、progress和result這三個泛型參數,其中params表示參數的類型,progress表示背景任務的執行進度和類型,而result則表示背景任務的傳回結果的類型,如果asynctask不需要傳遞具體的參數,那麼這三個泛型參數可以用void來代替。 關于線程池: asynctask對應的線程池threadpoolexecutor都是程序範圍内共享的,且都是static的,是以是asynctask控制着程序範圍内所有的子類執行個體。由于這個限制的存在,當使用預設線程池時,如果線程數超過線程池的最大容量,線程池就會爆掉(3.0後預設串行執行,不會出現個問題)。針對這種情況,可以嘗試自定義線程池,配合asynctask使用。 關于預設線程池: asynctask裡面線程池是一個核心線程數為cpu + 1,最大線程數為cpu * 2 + 1,工作隊列長度為128的線程池,線程等待隊列的最大等待數為28,但是可以自定義線程池。線程池是由asynctask來處理的,線程池允許tasks并行運作,需要注意的是并發情況下資料的一緻性問題,新資料可能會被老資料覆寫掉。是以 希望tasks能夠串行運作的話,使用serial_executor。 asynctask在不同的sdk版本中的差別: 調用asynctask的execute方法不能立即執行程式的原因及改善方案通過查閱官方文檔發現,asynctask首次引入時,異步任務是在一個獨立的線程中順序的執行,也就是說一次隻執行一個任務,不能并行的執行,從1.6開始,asynctask引入了線程池,支援同時執行5個異步任務,也就是說隻能有5個線程運作,超過的線程隻能等待,等待前的線程直到某個執行完了才被排程和運作。換句話說,如果程序中的asynctask執行個體個數超過5個,那麼假如前5都運作很長時間的話,那麼第6個隻能等待機會了。這是asynctask的一個限制,而且對于2.3以前的版本無法解決。如果你的應用需要大量的背景線程去執行任務,那麼隻能放棄使用asynctask,自己建立線程池來管理thread。不得不說,雖然asynctask較thread使用起來友善,但是它最多隻能同時運作5個線程,這也大大局限了它的作用,你必須要小心設計你的應用,錯開使用asynctask時間,盡力做到分時,或者保證數量不會大于5個,否就會遇到上面提到的問題。可能是google意識到了asyntask的局限性了,從android 3.0開始對asynctask的api做出了一些調整:每次隻啟動一個線程執行一個任務,完了之後再執行第二個任務,也就是相當于隻有一個背景線程在執行所送出的任務。 一些問題: 1.生命周期 很多開發者會認為一個在activity中建立的asynctask會随着activity的銷毀而銷毀。然而事實并非如此。asyntask會一直執行,直到doinbackground()方法執行完畢,然後,如果cancel(boolean)被調用,那麼oncancelled(result result)方法會被執行;否則,執行onpostexecute(result result)方法。如果我們的activity銷毀之前,沒有取消asynctask,這有可能讓我們的應用崩潰(crash)。因為它想要處理的view已經不存在了。是以,我們是必須確定在銷毀活動之前取消任務。總之,我們使用asynctask需要確定asynctask正确的取消。