標籤:android筆試題 android進階 android面試
關注finddreams部落格:http://blog.csdn.net/finddreams/article/details/44301359
上一篇文章我們已經瞭解了Android筆試的一些基礎題目,《Android開發面試經——2.常見Android基礎筆試題》
但是做為一個有經驗的開發人員,僅僅知道基礎題還是不夠的,你的簡曆上說有兩年以上工作經驗的話,那面試官肯定會問一些深入性的問題,看你能否回答的出。所以為了找一個更好的工作,我們還需要去瞭解一下Android進階的筆試題目:
1.什麼是ANR,如何避免?
ANR:Application Not Responding。
在 Android 中,Active Manager和視窗管理器這兩個系統服務負責監視應用程式的響應。當出現下列情況時,Android 就會顯示 ANR 對話方塊了:
①.使用者對應用程式的操作(如輸入事件,按鍵、觸控螢幕事件)在5秒內無響應
②. 廣播接受器(BroadcastReceiver)在10秒內仍未執行完畢
Android 應用程式完全運行在一個獨立的線程中(例如 main)。這就意味著,任何在主 線程中啟動並執行,需要消耗大量時間的操作都會引發 ANR。因為此時,你的應用程式已經沒有機會去響應輸入事件和意向廣播(Intentbroadcast)。
避免方法:Activity 應該在它的關鍵生命週期方法(如 onCreate()和 onResume())裡儘可能少的去做建立操作,
潛在的耗時操作。例如網路或資料庫操作,或者高耗時的計算如改變位元影像尺寸,應該在子線程裡(或者非同步方式)來完成。
主線程應該為子線程提供一個 Handler,以便完成時能夠提交給主線程。
2.Handler機制原理?
andriod 提供了 Handler 和 Looper 來滿足線程間的通訊。Handler 先進先出原則。
Looper 類用來管理特定線程內對象之間的訊息交換 (MessageExchange)。
1)Looper: 一個線程可以產生一個 Looper 對象,由它來管理此線程裡的 MessageQueue(訊息佇列)。
2)Handler: 你可以構造 Handler 對象來與 Looper 溝通,以便 push 新訊息到 MessageQueue 裡;或者接收 Looper 從 MessageQueue 取出)所送來的訊息。
3) Message Queue(訊息佇列 ): 用來存放線程放入的訊息。
4)線程: UI thread 通常就是 main thread, 而 Android 啟動程式時會替它建立一個 MessageQueue。
3.請解釋下在單執行緒模式中Message、Handler、Message Queue、Looper之間的關係。
簡單的說,Handler擷取當前線程中的 looper對象,looper 用來從存放 Message 的 MessageQueue中取出 Message,再有 Handler 進行 Message 的分發和處理.
Message Queue(訊息佇列): 用來存放通過 Handler 發布的訊息, 通常附屬於某一個建立它的線程,可以通過 Looper.myQueue()得到當前線程的訊息佇列
Handler:發行就緒或者處理一個訊息或者操作一個 Runnable,通過 Handler發布訊息, 訊息將只會發送到與它關聯的訊息佇列,然也只能處理該訊息佇列中的訊息
Looper:是 Handler 和訊息佇列之間通訊橋樑,程式組件首先通過 Handler 把訊息傳遞給 Looper,Looper 把訊息放入隊列。Looper 也把訊息佇列裡的訊息廣播給所有的
Handler:Handler 接受到訊息後調用 handleMessage進行處理
Message:訊息的類型,在 Handler 類中的 handleMessage 方法中得到單個的訊息進行處理
在單執行緒模式下, 為了線程通訊問題, Android 設計了一個 Message Queue(訊息佇列), 線程間可以通過該 Message Queue 並結合 Handler 和 Looper 組件進行資訊交換。
下面將對它 們進行分別介紹:
1. Message
Message 訊息,理解為線程間交流的資訊,處理資料後台線程需要更新 UI ,則發送Message 內含一些資料給 UI 線程。
2. Handler
Handler處理者,是 Message 的主要處理者,負責 Message 的發送,Message 內容的執行處理。後台線程就是通過傳進來的 Handler對象引用來 sendMessage(Message)。
而使用 Handler,需要 implement 該類的 handleMessage(Message)方法,它是處理這些
Message 的操作內容,例如 Update UI 。通常需要子類化 Handler 來實現 handleMessage方法。
3. Message Queue
Message Queue 訊息佇列,用來存放通過 Handler 發布的訊息,按照先進先出執行。每個 message queue 都會有一個對應的 Handler。Handler 會向 messagequeue 通過兩種方法發送訊息:sendMessage 或 post。這兩種訊息都會插在 message queue 隊尾並
按先進先出執行。但通過這兩種方法發送的訊息執行的方式略有不同:通過 sendMessage發送的是一個 message 對象,會被 Handler 的 handleMessage()函數處理;而通過 post 方法發送的是一個 runnable 對象,則會自己執行。
4. Looper
Looper 是每條線程裡的 Message Queue 的管家。Android 沒有 Global 的MessageQueue,而 Android 會自動替主線程(UI 線程)建立 Message Queue,但在子線程裡並沒有建立 Message Queue。 所以調用 Looper.getMainLooper()得到的主線程的 Looper 不為 NULL,但調用 Looper.myLooper()得到當前線程的 Looper 就有可能為 NULL。
4.Android 中線程與線程,進程與進程之間如何通訊
1、一個 Android 程式開始運行時,會單獨啟動一個 Process。
預設情況下,所有這個程式中的 Activity 或者 Service 都會跑在這個 Process。
預設情況下,一個 Android 程式也只有一個 Process,但一個 Process 下卻可以有許多個 Thread。
2、一個 Android 程式開始運行時,就有一個主線程 MainThread 被建立。該線程主要負責 UI 介面的顯示、更新和控制項互動,所以又叫 UI Thread。
一個 Android 程式建立之初,一個 Process 呈現的是單執行緒模式–即 Main Thread,
所有的任務都在一個線程中運行。所以,Main Thread 所調用的每一個函數,其耗時應該
越短越好。而對於比較費時的工作,應該設法交給子線程去做,以避免阻塞主線程(主線程被阻塞,會導致程式假死 現象) 。
3、Android 單執行緒模式:Android UI 操作並不是安全執行緒的並且這些操作必須在 UI 線程中執行。如果在子線程中直接修改 UI,會導致異常。
4.Android 的 的 IPC ( 處理序間通訊 ) 機制
IPC 是內部進程通訊的簡稱, 是共用 ” 具名管道 ” 的資源。Android 中的 IPC機制是為了讓
Activity 和 Service之間可以隨時的進行互動,故在 Android 中該機制,只適用於 Activity 和 Service之間的通訊,類似於遠程方法調用,類似於 C/S 模式的訪問。通過定義 AIDL 介面檔案來定義 IPC 介面。Servier 端實現 IPC介面,Client 端調用 IPC介面本地代理。
5.Android應用程式架構
6.View, surfaceView, GLSurfaceView的區別
View 是最基礎的,必須在 UI 主線程內更新畫面,速度較慢。
SurfaceView 是 view 的子類,類似使用雙緩機制,在新的線程中更新畫面所以重新整理介面速度比 view 快 GLSurfaceView 是 SurfaceView 的子類,opengl 專用的。
區別:SurfaceView是從View基類中派生出來的顯示類,直接子類有GLSurfaceView和VideoView,可以看出GL和視頻播放以及Camera網路攝影機一般均使用SurfaceView
SurfaceView和View最本質的區別在於,surfaceView是在一個新起的單獨線程中可以重新繪製畫面而View必須在UI的主線程中更新畫面。
那麼在UI的主線程中更新畫面 可能會引發問題,比如你更新畫面的時間過長,那麼你的主UI線程會被你正在畫的函數阻塞。那麼將無法響應按鍵,觸屏等訊息。
當使用surfaceView 由於是在新的線程中更新畫面所以不會阻塞你的UI主線程。但這也帶來了另外一個問題,就是事件同步。比如你觸屏了一下,你需要surfaceView中thread處理,一般就需要有一個event queue的設計來儲存touch event,這會稍稍複雜一點,因為涉及到線程同步。
7. AIDL的全稱是什嗎?如何工作?
AIDL 全稱 Android Interface Definition Language(Android 介面描述語言)是一種介面描述語言 ; 編譯器可以通過 aidl檔案產生一段代碼, 通過預先定義的介面達到兩個進程內
部通訊進程跨界對象訪問的目的.AIDL 的 IPC 的機制和 COM 或 CORBA 類似 , 是基於介面的, 但它是輕量級的。 它使用代理類在用戶端和實現層間傳遞值 . 如果要使用 AIDL, 需要完成2件事情 :
1. 引入AIDL的相關類 .;
2. 調用 aidl產生的 class.理論上 , 參數可以傳遞基礎資料型別 (Elementary Data Type)和String, 還有就是Bundle的衍生類別
當A進程要去調用B進程中的service時,並實現通訊,我們通常都是通過AIDL來操作的 。
A工程:
首先我們在net.blogjava.mobile.aidlservice包中建立一個RemoteService.aidl檔案,在裡面我們自訂一個介面,含有方法get。ADT外掛程式會在gen目錄下自動產生一個RemoteService.java檔案,該類中含有一個名為RemoteService.stub的內部類,該內部類中含有aidl檔案介面的get方法。
說明一:aidl檔案的位置不固定,可以任意
然後定義自己的MyService類,在MyService類中自訂一個內部類去繼承RemoteService.stub這個內部類,實現get方法。在onBind方法中返回這個內部類的對象,系統會自動將這個對象封裝成IBinder對象,傳遞給他的調用者。
其次需要在AndroidManifest.xml檔案中配置MyService類,代碼如下:
<!-- 註冊服務 --> <service android:name=".MyService"> <intent-filter> <!-- 指定調用AIDL服務的ID --> <action android:name="net.blogjava.mobile.aidlservice.RemoteService" /> </intent-filter> </service>
為什麼要指定調用AIDL服務的ID,就是要告訴外界MyService這個類能夠被別的進程訪問,只要別的進程知道這個ID,正是有了這個ID,B工程才能找到A工程實現通訊。
說明:AIDL並不需要許可權
B工程:
首先我們要將A工程中產生的RemoteService.java檔案拷貝到B工程中,在bindService方法中綁定aidl服務
綁定AIDL服務就是將RemoteService的ID作為intent的action參數。
說明:如果我們單獨將RemoteService.aidl檔案放在一個包裡,那個在我們將gen目錄下的該包拷貝到B工程中。如果我們將RemoteService.aidl檔案和我們的其他類存放在一起,那麼我們在B工程中就要建立相應的包,以保證RmoteService.java檔案的報名正確,我們不能修改RemoteService.java檔案
bindService(new Inten(“net.blogjava.mobile.aidlservice.RemoteService”), serviceConnection, Context.BIND_AUTO_CREATE);
ServiceConnection的onServiceConnected(ComponentName name, IBinder service)方法中的service參數就是A工程中MyService類中繼承了RemoteService.stub類的內部類的對象。
Android開發面試經——3.常見Android進階筆試題