Android 面試題匯總

  • 記錄自己面試和網上別人面試遇到的題目匯總。部分內容來自網絡钦椭,若有侵權請聯(lián)系我刪除
  • 后續(xù)補充會先在 GitHub 上更新,歡迎補充

基礎知識


Service生命周期


  • service的生命周期分為兩種

    生命周期
    生命周期

Android中的幾種動畫


  • 補間動畫 :是對某個View進行一系列的動畫的操作碑诉,包括淡入淡出(Alpha)彪腔,縮放(Scale),平移(Translate)进栽,旋轉(Rotate)四種模式德挣。

  • 幀動畫 : 將多張圖片組合起來進行播放,類似于早期電影的工作原理快毛,很多App的loading是采用這種方式

  • 屬性動畫 : 屬性動畫不再僅僅是一種視覺效果了格嗅,而是一種不斷地對值進行操作的機制,并將值賦到指定對象的指定屬性上祸泪,可以是任意對象的任意屬性

從ActivityA跳轉到ActivityB的生命周期調用順序


  • 打開ActivityA

    onCreate(A) -> onStart(A) -> onResume(A)
    
  • 打開ActivityB

    onPause(A) -> onCreate(B) -> onStart(B) -> onResume(B) -> onStop(A)
    
  • 回到ActivtyA

    onPause(B) -> onRestart(A) -> onStart(A) -> onResume(A) -> onStop(B) -> onDestory(B)
    

HandlerThread的原理


判斷處于主線程還是子線程


//1
Looper.getMainLooper() == Looper.myLooper();

//2
Looper.getMainLooper().getThread() == Thread.currentThread();

//3
Looper.getMainLooper().getThread().getId() == Thread.currentThread().getId();

設計模式


面向對象六大原則 單例模式 Builder模式
原型模式 簡單工廠 工廠方法模式
抽象工廠模式 策略模式 狀態(tài)模式
責任鏈模式 解釋器模式 命令模式
觀察者模式 備忘錄模式 迭代器模式
模板方法模式 訪問者模式 中介者模式
代理模式 組合模式 適配器模式
裝飾模式 享元模式 外觀模式

onMeasure返回的兩個參數都有什么信息


View繪制流程


Activity的創(chuàng)建過程


ActivityManagerService -> </br>
ActivityStackSupervisor -> </br>
ActivityStack -> </br>
ActivityStackSupervisor -> </br>
ApplicationThread

Handler


  • Handler 是Android類庫提供的用于接受、傳遞和處理消息或Runnable對象的處理類阀湿,它結合Message赶熟、MessageQueue和Looper類以及當前線程實現(xiàn)了一個消息循環(huán)機制,用于實現(xiàn)任務的異步加載和處理

  • 主要用途

    • 執(zhí)行定時任務 指定任務時間陷嘴,在某個具體時間或某個時間段后執(zhí)行特定的任務操作映砖,例如使用Handler提供的postDelayed(Runnable r,long delayMillis)方法指定在多久后執(zhí)行某項操作

    • 線程間的通信 在執(zhí)行較為耗時的操作時,Handler負責將子線程中執(zhí)行的操作的結果傳遞到UI線程灾挨,然后UI線程再根據傳遞過來的結果進行相關UI元素的更新

  • Handler用法

    示意圖
  • 根據上面的圖片邑退,我們現(xiàn)在來解析一下異步消息處理機制

    • Message:消息體,用于裝載需要發(fā)送的對象

    • handler:它直接繼承自Object劳澄。作用是:在子線程中發(fā)送Message或者Runnable對象到MessageQueue中地技;在UI線程中接收、處理從MessageQueue分發(fā)出來的Message或者Runnable對象秒拔。發(fā)送消息一般使用Handler的sendMessage()方法莫矗,而發(fā)出去的消息經過處理后最終會傳遞到Handler的handlerMessage()方法中

    • MessageQueue用于存放Message或Runnable對象的消息隊列。它由對應的Looper對象創(chuàng)建砂缩,并由Looper對象管理作谚。每個線程中都只會有一個MessageQueue對象

    • Looper:是每個線程中的MessageQueue的管家,循環(huán)不斷地管理MessageQueue接收和分發(fā)Message或Runnable的工作庵芭。調用Looper的loop()方法后妹懒,就會進入到一個無限循環(huán)中然后每當發(fā)現(xiàn)MessageQueue中存在一條消息,就會將它取出喳挑,并調用Handler的handlerMessage()方法彬伦。每個線程中也只會有一個Looper對象

  • Handler和Looper對象是屬于線程內部的數據滔悉,不過也提供與外部線程的訪問接口伊诵,Handler就是公開給外部線程的接口,用于線程間的通信回官。Looper是由系統(tǒng)支持的用于創(chuàng)建和管理MessageQueue的依附于一個線程的循環(huán)處理對象曹宴,而Handler是用于操作線程內部的消息隊列的,所以Handler也必須依附一個線程歉提,而且只能是一個線程

  • 鏈接

解釋下Application類


  • 定義

    • 用于維護全局應用程序狀態(tài)的基礎類
    • 代表應用程序的類笛坦,也屬于Android中的一個系統(tǒng)組件
    • 繼承關系: 繼承自 ContextWarpper 類
  • Application 與 Context

    • Activity、Service苔巨、Application 都是 Context 的子類版扩。Context 是一個抽象類,具體的實現(xiàn)是在 ContextImpl 類中侄泽。因此應用程序 APP 共用的 Context 數目公式為:
      context數 = Service數 + Actvity數 + 1(Application 對應的 Context 實例)
      
  • 特點

    • 實例創(chuàng)建方式:單例模式

      • 每個 APP 運行時會首先自動創(chuàng)建 application 類并實例化 application 對象且只有一個(即 application 類是單例模式)
      • 可以通過繼承 application 來實現(xiàn)自定義的 application 類
    • 實例形式:全局模式礁芦,即不同組件都可以獲得 application 對象且都是同一個

    • 生命周期:等于 APP 的生命周期.

  • 連接

APK安裝過程


  • APK安裝的主要步驟

    • 將 apk 文件復制到 /data/app/ 目錄下
    • 解壓 apk ,拷貝文件, 創(chuàng)建應用的數據目錄
    • 解析 apk 的AndroidManifinest.xml 文件
    • 顯示快捷方式
  • 鏈接

MultiDex工作原理分析和優(yōu)化方案


應用啟動流程分析


View的測量寬/高和最終寬/高有什么區(qū)別(另一種問法: view 的 getMeasuredWidth 和 getWidth 有什么區(qū)別)


  • 在 View 的默認實現(xiàn)中 View 的測量寬/高和最終寬/高是相等的柿扣,只不過 測量寬高(getMeasureWidth/Height)是在 view 的 measure 過程中調用的肖方,而 view 的 最終寬高(getWidth/Height)是在 view 的 layout 過程中調用的;即兩者的賦值時機不同,測量寬高比最終寬高獲取的時機稍微早點;

  • 在一般開發(fā)中這兩者的值是一樣的未状,但是也會存在特殊情況俯画,

    • 比如在 view 的 layout 方法中:

      public void layout(int l, int t, int r, int b){
           super.layout(l, t, r+100, b+100);
      }
      

      這個步驟就會導致測量寬高比最終寬高小 100px

    • 另一種情況是在某些情況下 View 需要多次 measure 才能確定自己的測量寬高,在前幾次的測量寬高過程中得出的值可能和最終寬高的不一致司草,但最終來說:測量寬高和最終寬高相等

事件分發(fā)流程


  • Android事件分發(fā)流程

    Activity(Windwos) -> ViewGroup -> View
    
    流程圖說明
    • 對于dispatchTouchEvent , onTouchEvent 返回 true 就是自己消費了艰垂,返回 false 就傳到父View 的onTouchEvent方法
    • ViewGroup 想把事件分發(fā)給自己的 onTouchEvent,需要在onInterceptTouchEvent方法中返回 true 把事件攔截下來
    • ViewGroup 的 onInterceptTouchEvent 默認不攔截,所以 super.onInterceptTouchEvent() = false
    • View(這里指沒有子View)沒有攔截器,所以 View 的dispatchTouchEventsuper.dispatchTouchEvent(event)默認把事件分發(fā)給自己的onTouchEvent

View的渲染機制


編譯打包的過程


  • 等待補充

ANR的原理(源碼角度)


  • 等待補充

屬性動畫的原理

  • 等待補充

Android有多個資源文件夾材泄,應用在不同分辨率下是如何查找對應文件夾下的資源的,描述整個過程


  • 等待補充

應用最多占可被分配多少內存


-> 進程數*16M

一個應用中有多少個 Window


為什么Dialog不能用Application的Context


  • Dialog初化始時是通過Context.getSystemServer 來獲取 WindowManager,而如果用Application或者Service的Context去獲取這個WindowManager服務的話急灭,會得到一個WindowManagerImpl的實例姐浮,這個實例里token也是空的。之后在Dialog的show方法中將Dialog的View(PhoneWindow.getDecorView())添加到WindowManager時會給token設置默認值還是null葬馋。
    如果這個Context是Activity卖鲤,則直接返回Activity的mWindowManager,這個mWindowManager在Activity的attach方法被創(chuàng)建畴嘶,Token指向此Activity的Token蛋逾,mParentWindow為Activity的Window本身

  • 答案

    那為什么一定要是Activity的Token呢?我想使用Token應該是為了安全問題窗悯,通過Token來驗證WindowManager服務請求方是否是合法的区匣。如果我們可以使用Application的Context,或者說Token可以不是Activity的Token蒋院,那么用戶可能已經跳轉到別的應用的Activity界面了亏钩,但我們卻可以在別人的界面上彈出我們的Dialog,想想就覺得很危險欺旧。

Android Activity 姑丑、 Window 、 View之間的關系


  • 如圖

關于Android Force Close 出現(xiàn)的原因 以及解決方法


  • 原因

    • Error
    • OOM , 內存溢出
    • StackOverFlowError
    • RuntimeException(比如空指針異常)
  • 如何避免

    • 可以實現(xiàn)Thread.UncaughtExceptionHandler接口的uncaughtException方法

哪些情況會出現(xiàn)內存泄漏辞友,如何解決


  • 對于使用了Boardcast Receive栅哀、ContentObserver、File、Cursor昌屉、Stream钙蒙、Bitmap等資源的時候沒有銷毀。

    解決方法 -> 應該在不使用的時候關閉或者注銷

  • 靜態(tài)內部類持有外部成員變量

    解決方法 -> 可以使用若引用

  • 使用了 context 持有 Activity 導致 Activity無法釋放

    解決方法 -> 使用 ApplicationContext

  • 集合中沒有使用的對象沒有及時 remove

  • handler 引起的內存泄漏

    解決方法 -> 使用若引用持有 Activity等的 Context

  • 設置過的Listener沒有及時移除

    解決方法 -> 在destory 里 設置 Listener 為 null

Android系統(tǒng)的架構


關于第三庫問題


Glide4.0源碼解析


otto源碼解析


  • otto 這個開源項目是一個event bus模式的消息框架间驮,用于程序各個模塊之間的通信躬厌,此消息框架可以使得各個
    模塊之間減少耦合性。

  • 鏈接

Gilde怎么實現(xiàn)圓角圖


  • 實現(xiàn)原理 利用 Transform
  • 代碼示例
    public class GlideRoundTransform extends BitmapTransformation {
    
    private static float radius = 0f;
    
    /**
     * 構造函數 默認圓角半徑 4dp
     *
     * @param context Context
     */
    public GlideRoundTransform(Context context) {
        this(context, 4);
    }
    
    /**
     * 構造函數
     *
     * @param context Context
     * @param dp      圓角半徑
     */
    public GlideRoundTransform(Context context, int dp) {
        super(context);
        radius = Resources.getSystem().getDisplayMetrics().density * dp;
    }
    
    @Override
    protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
        return roundCrop(pool, toTransform);
    }
    
    private static Bitmap roundCrop(BitmapPool pool, Bitmap source) {
        if (source == null) return null;
    
        Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
        if (result == null) {
            result = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
        }
    
        Canvas canvas = new Canvas(result);
        Paint paint = new Paint();
        paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
        paint.setAntiAlias(true);
        RectF rectF = new RectF(0f, 0f, source.getWidth(), source.getHeight());
        canvas.drawRoundRect(rectF, radius, radius, paint);
        return result;
    }
    
    @Override
    public String getId() {
        return getClass().getName() + Math.round(radius);
    }
    }
    

其他鏈接


最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末竞帽,一起剝皮案震驚了整個濱河市扛施,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌屹篓,老刑警劉巖疙渣,帶你破解...
    沈念sama閱讀 222,681評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異堆巧,居然都是意外死亡妄荔,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評論 3 399
  • 文/潘曉璐 我一進店門谍肤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來啦租,“玉大人,你說我怎么就攤上這事荒揣∨窠牵” “怎么了?”我有些...
    開封第一講書人閱讀 169,421評論 0 362
  • 文/不壞的土叔 我叫張陵系任,是天一觀的道長恳蹲。 經常有香客問我,道長俩滥,這世上最難降的妖魔是什么嘉蕾? 我笑而不...
    開封第一講書人閱讀 60,114評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮举农,結果婚禮上荆针,老公的妹妹穿的比我還像新娘敞嗡。我一直安慰自己颁糟,他們只是感情好,可當我...
    茶點故事閱讀 69,116評論 6 398
  • 文/花漫 我一把揭開白布喉悴。 她就那樣靜靜地躺著棱貌,像睡著了一般。 火紅的嫁衣襯著肌膚如雪箕肃。 梳的紋絲不亂的頭發(fā)上婚脱,一...
    開封第一講書人閱讀 52,713評論 1 312
  • 那天,我揣著相機與錄音,去河邊找鬼障贸。 笑死错森,一個胖子當著我的面吹牛,可吹牛的內容都是我干的篮洁。 我是一名探鬼主播涩维,決...
    沈念sama閱讀 41,170評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼袁波!你這毒婦竟也來了瓦阐?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 40,116評論 0 277
  • 序言:老撾萬榮一對情侶失蹤篷牌,失蹤者是張志新(化名)和其女友劉穎睡蟋,沒想到半個月后,有當地人在樹林里發(fā)現(xiàn)了一具尸體枷颊,經...
    沈念sama閱讀 46,651評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡戳杀,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,714評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了夭苗。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片豺瘤。...
    茶點故事閱讀 40,865評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖听诸,靈堂內的尸體忽然破棺而出坐求,到底是詐尸還是另有隱情,我是刑警寧澤晌梨,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布桥嗤,位于F島的核電站,受9級特大地震影響仔蝌,放射性物質發(fā)生泄漏泛领。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,211評論 3 336
  • 文/蒙蒙 一敛惊、第九天 我趴在偏房一處隱蔽的房頂上張望渊鞋。 院中可真熱鬧,春花似錦瞧挤、人聲如沸锡宋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽执俩。三九已至,卻和暖如春癌刽,著一層夾襖步出監(jiān)牢的瞬間役首,已是汗流浹背尝丐。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留衡奥,地道東北人爹袁。 一個月前我還...
    沈念sama閱讀 49,299評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像矮固,于是被迫代替她去往敵國和親呢簸。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,870評論 2 361

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,328評論 25 707
  • 1乏屯,java 接口的意義: 規(guī)范根时,擴展,回調 規(guī)范:比如辰晕,有兩個及上的的類擁有相同的方法蛤迎,但是實現(xiàn)功能不一樣,就可...
    漫唐閱讀 971評論 0 6
  • Java中的String類可以被繼承么含友? 答:不能替裆,因為它是一個final類,同樣的還有Integer窘问,F(xiàn)loat...
    gyymz1993閱讀 4,000評論 2 104
  • 谷雨嬰幼兒玩具有限公司 【日精進打卡第28天】 【知~學習】 《六項精進》背讀145遍 《大學》誦讀 74遍 《六...
    一池清水_8fd9閱讀 118評論 0 0
  • 薛明宇屬于林三爺的貴客辆童,而且這里極度偏僻,倒是適合薛明宇這種紈绔大少享受惠赫。 為了找到薛明宇把鉴,機場,火車站儿咱,乃至長途...
    飄雲閱讀 225評論 0 1