這部分面試題基本都是在2011年常見的。
發幾個常見。大部分直接copy
其實好多你只要理解大致的意思就行了。解答都是偏長。
1.如何避免ANR?
答:ANR:Application Not Responding,五秒在Android中,活動管理器和窗口管理器這兩個系統服務負責監視應用程序的響應。當出現下列情況時,Android就會顯示ANR對話框了: 對輸入事件(如按鍵、觸摸屏事件)的響應超過5秒 意向接受器(intentReceiver)超過10秒鍾仍未執行完畢
Android應用程序完全運行在一個獨立的線程中(例如main)。這就意味着,任何在主線程中運行的,需要消耗大量時間的操作都會引發ANR。因為此時,你的應用程序已經沒有機會去響應輸入事件和意向廣播(Intent broadcast)。 因此,任何運行在主線程中的方法,都要盡可能的只做少量的工作。特別是活動生命周期中的重要方法如onCreate()和 onResume()等更應如此。潛在的比較耗時的操作,如訪問網絡和數據庫;或者是開銷很大的計算,比如改變位圖的大小,需要在一個單獨的子線程中完成(或者是使用異步請求,如數據庫操作)。但這並不意味着你的主線程需要進入阻塞狀態已等待子線程結束 -- 也不需要調用Therad.wait()或者Thread.sleep()方法。取而代之的是,主線程為子線程提供一個句柄(Handler),讓子線程在即將結束的時候調用它(xing:可以參看Snake的例子,這種方法與以前我們所接觸的有所不同)。使用這種方法涉及你的應用程序,能夠保證你的程序對輸入保持良好的響應,從而避免因為輸入事件超過5秒鍾不被處理而產生的ANR。這種實踐需要應用到所有顯示用戶界面的線程,因為他們都面臨着同樣的超時問題。
2. handler機制的原理
答 :andriod提供了 Handler 和 Looper 來滿足線程間的通信。Handler 先進先出原則。Looper類用來管理特定線程內對象之間的消息交換(Message Exchange)。 1)Looper: 一個線程可以產生一個Looper對象,由它來管理此線程里的Message Queue(消息隊列)。 2)Handler: 你可以構造Handler對象來與Looper溝通,以便push新消息到Message Queue里;或者接收Looper從Message Queue取出)所送來的消息。 3) Message Queue(消息隊列):用來存放線程放入的消息。 4)線程:UI thread 通常就是main thread,而Android啟動程序時會替它建立一個Message Queue。
3. Android引入廣播機制的用意?
答:a:從MVC的角度考慮(應用程序內) 其實回答這個問題的時候還可以這樣問,android為什么要有那4大組件,現在的移動開發模型基本上也是照搬的web那一套MVC架構,只不過是改了點嫁妝而已。android的四大組件本質上就是為了實現移動或者說嵌入式設備上的MVC架構,它們之間有時候是一種相互依存的關系,有時候又是一種補充關系,引入廣播機制可以方便幾大組件的信息和數據交互。 b:程序間互通消息(例如在自己的應用程序內監聽系統來電) c:效率上(參考UDP的廣播協議在局域網的方便性) d:設計模式上(反轉控制的一種應用,類似監聽者模式)
4.什么情況會導致Force Close ?如何避免?能否捕獲導致其的異常? 答:一般像空指針啊,可以看起logcat,然后對應到程序中 來解決錯誤。
(這個問題完全看心情來回答。。。)
5.如何將一個Activity設置成窗口的樣式。
講點輕松的吧,可能有人希望做出來的應用程序是一個漂浮在手機主界面的東西,那么很 簡單你只需要設置 一下Activity的主題就可以了在AndroidManifest.xml 中定義 Activity的 地方一句話: Xml代碼 1. android :theme="@android:style/Theme.Dialog" 3. android:theme="@android:style/Theme.Dialog" android :theme="@android:style/Theme.Dialog" android:theme="@android:style/Theme.Dialog" 這就使你的應用程序變成對話框的形式彈出來了,或者 Xml代碼 1. android:theme="@android:style/Theme.Translucent" 3. android:theme="@android:style/Theme.Translucent" 就變成半透明的,[友情提示-.-]類似的這種activity的屬性可以在android.R.styleable 類的AndroidManifestActivity 方法中看到,AndroidManifest.xml中所有元素的屬性的介紹都可以參考這個類android.R.styleable 上面說的是屬性名稱,具體有什么值是在android.R.style中 可以看到,比如這個"@android:style/Theme.Dialog" 就對應於android.R.style.Theme_Dialog ,('_'換成'.' < --注意:這個是文章內容不是笑臉)就可以用在描述文件 中了,找找類定義和描述文件中的對應關系就都明白了。
(簡單來說直接在配置文件引入風格。追求效果的應用此用法用到挺多);
6、IntentService有何優點?
Acitivity的進程,當處理Intent的時候,會產生一個對應的Service Android的進程處理器現在會盡可能的不kill掉你 非常容易使用
(這回答其實比較。。。其實我也不知道干嘛使,因為看幫助文檔就說了一個用來處理異步請求的service,工作完了自己停止。沒用過,不做評價)。
7、說說mvc模式的原理,它在android中的運用,android的官方建議應用程序的開發采用mvc模式。何謂mvc? mvc是model,view,controller的縮寫,mvc包含三個部分: 模型(model)對象:是應用程序的主體部分,所有的業務邏輯都應該寫在該層。 視圖(view)對象:是應用程序中負責生成用戶界面的部分。也是在整個mvc架構中用戶唯一可以看到的一層,接收用戶的輸入,顯示處理結果。 控制器(control)對象:是根據用戶的輸入,控制用戶界面數據顯示及更新model對象狀態的部分,控制器更重要的一種導航功能,想用用戶出發的相關事件,交給m哦得了處理。 android鼓勵弱耦合和組件的重用,在android中mvc的具體體現如下: 1)視圖層(view):一般采用xml文件進行界面的描述,使用的時候可以非常方便的引入,當然,如何你對android了解的比較的多了話,就一定可以想到在android中也可以使用javascript+html等的方式作為view層,當然這里需要進行java和javascript之間的通信,幸運的是,android提供了它們之間非常方便的通信實現。 2)控制層(controller):android的控制層的重任通常落在了眾多的acitvity的肩上,這句話也就暗含了不要在acitivity中寫代碼,要通過activity交割model業務邏輯層處理,這樣做的另外一個原因是android中的acitivity的響應時間是5s,如果耗時的操作放在這里,程序就很容易被回收掉。3)模型層(model):對數據庫的操作、對網絡等的操作都應該在model里面處理,當然對業務計算等操作也是必須放在的該層的。
8、AIDL的全稱是什么?如何工作?能處理哪些類型的數據?
AIDL全稱Android Interface Definition Language(AndRoid接口描述語言) 是一種借口描述語言; 編譯器可以通過aidl文件生成一段代碼,通過預先定義的接口達到兩個進程內部通信進程跨界對象訪問的目的.AIDL的IPC的機制和COM或CORBA類似, 是基於接口的,但它是輕量級的。它使用代理類在客戶端和實現層間傳遞值. 如果要使用AIDL, 需要完成2件事情: 引入AIDL的相關類.; 調用aidl產生的class.理論上, 參數可以傳遞基本數據類型和String, 還有就是Bundle的派生類, 不過在Eclipse中,目前的ADT不支持Bundle做為參數. 具體實現步驟如下: 1.創建AIDL文件, 在這個文件里面定義接口, 該接口定義了可供客戶端訪問的方法和屬性。2.編譯AIDL文件, 用Ant的話, 可能需要手動, 使用Eclipse plugin 的話,可以根據adil文件自動生產java文件並編譯, 不需要人為介入. 3.在Java文件中, 實現AIDL中定義的接口. 編譯器會根據AIDL接口, 產生一個JAVA接口。這個接口有一個名為Stub的內部抽象類,它繼承擴展了接口並實現了遠程調用需要的幾個方法。接下來就需要自己去實現自定義的幾個接口了.4.向客戶端提供接口ITaskBinder, 如果寫的是service,擴展該Service並重載onBind ()方法來返回一個實現上述接口的類的實例。5.在服務器端回調客戶端的函數. 前提是當客戶端獲取的IBinder接口的時候,要去注冊回調函數, 只有這樣, 服務器端才知道該調用那些函數.AIDL語法很簡單,可以用來聲明一個帶一個或多個方法的接口,也可以傳遞參數和返回值。 由於遠程調用的需要, 這些參數和返回值並不是任何類型.下面是些AIDL支持的數據類型: 1. 不需要import聲明的簡單Java編程語言類型(int,boolean等) 2. String, CharSequence不需要特殊聲明 3. List, Map和Parcelables類型, 這些類型內所包含的數據成員也只能是簡單數據類型, String等其他比支持的類型. (另外: 我沒嘗試Parcelables, 在Eclipse+ADT下編譯不過, 或許以后會有所支持). 實現接口時有幾個原則: 1>拋出的異常不要返回給調用者. 跨進程拋異常處理是不可取的。 2>IPC調用是同步的。如果你知道一個IPC服務需要超過幾毫秒的時間才能完成地話,你應該避免在Activity的主線程中調用。 也就是IPC調用會掛起應用程序導致界面失去響應. 這種情況應該考慮單起一個線程來處理。 3>不能在AIDL接口中聲明靜態屬性。 IPC的調用步驟:1. 聲明一個接口類型的變量,該接口類型在.aidl文件中定義。2. 實現ServiceConnection。3. 調用ApplicationContext.bindService(),並在ServiceConnection實現中進行傳遞. 4. 在ServiceConnection.onServiceConnected()實現中,你會接收一個IBinder實例(被調用的Service). 調用 YourInterfaceName.Stub.asInterface((IBinder)service)將參數轉換為YourInterface類型。 5. 調用接口中定義的方法。 你總要檢測到DeadObjectException異常,該異常在連接斷開時被拋出。它只會被遠程方法拋出。 6. 斷開連接,調用接口實例中的ApplicationContext.unbindService()
9、 如何退出Activity?如何安全退出已調用多個Activity的Application?對於單一Activity的應用來說,退出很簡單,直接finish()即可。當然,也可以用killProcess()和System.exit()這樣的方法。 但是,對於多Activity的應用來說,在打開多個Activity后,如果想在最后打開的Activity直接退出,上邊的方法都是沒有用的,因為上邊的方法都是結束一個Activity而已。 當然,網上也有人說可以。 就好像有人問,在應用里如何捕獲Home鍵,有人就會說用keyCode比較KEYCODE_HOME即可,而事實上如果不修改framework,根本不可能做到這一點一樣。所以,最好還是自己親自試一下。 那么,有沒有辦法直接退出整個應用呢?在2.1之前,可以使用ActivityManager的restartPackage方法。 它可以直接結束整個應用。在使用時需要權限android.permission.RESTART_PACKAGES。 注意不要被它的名字迷惑。可是,在2.2,這個方法失效了。在2.2添加了一個新的方法,killBackgroundProcesses(),需要權限 android.permission.KILL_BACKGROUND_PROCESSES。可惜的是,它和2.2的restartPackage一樣,根本起不到應有的效果。另外還有一個方法,就是系統自帶的應用程序管理里,強制結束程序的方法,forceStopPackage()。它需要權限android.permission.FORCE_STOP_PACKAGES。並且需要添加android:sharedUserId="android.uid.system"屬性。同樣可惜的是,該方法是非公開的,他只能運行在系統進程,第三方程序無法調用。 因為需要在Android.mk中添加LOCAL_CERTIFICATE := platform。 而Android.mk是用於在Android源碼下編譯程序用的。 從以上可以看出,在2.2,沒有辦法直接結束一個應用,而只能用自己的辦法間接辦到。 現提供幾個方法,供參考: 1、拋異常強制退出: 該方法通過拋異常,使程序Force Close。 驗證可以,但是,需要解決的問題是,如何使程序結束掉,而不彈出Force Close的窗口。 2、記錄打開的Activity: 每打開一個Activity,就記錄下來。在需要退出時,關閉每一個Activity即可。 3、發送特定廣播: 在需要結束應用時,發送一個特定的廣播,每個Activity收到廣播后,關閉即可。 4、遞歸退出 在打開新的Activity時使用startActivityForResult,然后自己加標志,在onActivityResult中處理,遞歸關閉。除了第一個,都是想辦法把每一個Activity都結束掉,間接達到目的。但是這樣做同樣不完美。你會發現,如果自己的應用程序對每一個Activity都設置了nosensor,在兩個Activity結束的間隙,sensor可能有效了。但至少,我們的目的達到了,而且沒有影響用戶使用。為了編程方便,最好定義一個Activity基類,處理這些共通問題。
(話說項目前期我也試過一個應用的完整退出,用的就是記錄activity,應用退出時遞歸。當時我看一個應用是否完整退出時進設置看應用管理,點擊你的應用,在卸載同一個界面你能看到一個選項,是否強行關閉。吐過有這個按鈕,就是沒退出。
現在是希望應用不要被強殺,流氓的占據着進程,因為需要后台推送服務端的數據。)
10、android中有哪幾種解析xml的類,官方推薦哪種?以及它們的原理和區別、 Android dvm的進程和Linux的進程, 應用程序的進程是否為同一個概念
DVM指dalivk的虛擬機。每一個Android應用程序都在它自己的進程中運行,都擁有一個獨立的Dalvik虛擬機實例。而每一個DVM都是在Linux 中的一個進程,所以說可以認為是同一個概念。 11、sim卡的EF 文件有何作用 sim卡的文件系統有自己規范,主要是為了和手機通訊,sim本 身可以有自己的操作系統,EF就是作存儲並和手機通訊用的 12、嵌入式操作系統內存管理有哪幾種, 各有何特性 頁式,段式,段頁,用到了MMU,虛擬空間等技術 13、 什么是嵌入式實時操作系統, Android 操作系統屬於實時操作系統嗎?嵌入式實時操作系統是指當外界事件或數據產生時,能夠接受並以足夠快的速度予以處理,其處理的結果又能在規定的時間之內來控制生產過程或對處理系統作出快速響應,並控制所有實時任務協調一致運行的嵌入式操作系統。主要用於工業控制、 軍事設備、 航空航天等領域對系統的響應時間有苛刻的要求,這就需要使用實時系統。又可分為軟實時和硬實時兩種,而android是基於linux內核的,因此屬於軟實時。
14、 ListView 的優化方案
答:1、如果自定義適配器,那么在 getView 方法中要考慮方法傳進來的參數 contentView 是否為 null,如果為 null 就創建 contentView 並返回,如果不為 null 則直接使用。在這個方法中盡可能少創建 view。
(這個其實還是很有實際意義)。
----------------------------------以下是自己項目或是被問到的幾個問題。
15.讓你說出一個自定義控件的流程。
答:這個看你自己,我被聞到過一個自定的progressbar。說里面不停轉動的圖片怎么實現。
16.說下輕量級的異步實現 AsyncTask,你的理解。
答:我不明白哪家公司給我這面試題為什么流了1頁的版塊來回答?我都不知道怎么扯。詳情實例請見 :http://blog.csdn.net/nono_love_lilith/article/details/7172743
17.控制Dialog彈出的位置?
答:直接代碼Window w=mDialog.getWindow(); WindowManager.LayoutParams lp =w.getAttributes(); lp.x=0; lp.y=20;mDialog.onWindowAttributesChanged(lp); mDialog.show();
18、關於 has leaked Window;。。。。。報錯的問題
答:這個問題很容易出現在在有彈出彈出對話框界面中
窗口泄露,此問題大多是是Activity關閉時,托管的對話框等沒有關閉引起的。
19.關於自定義Activity標題后背景無法填充完整?
此問題轉次某個論壇的某哥們。我遇到的是背景無法填充完整。----- 若修改標題欄高度,請修改android:windowTitleSize 這句拯救了我。 答: window初始化,加載標題的地方,咱也不知道在哪里,不過咱能以layout作為切入點。打開源碼里面的layout文件夾,找跟標題欄相關的xml文件。里面有screen_title.xml和screen_custom_title.xml,這就是咱們要找的目標了。 既然是自定義標題,那我們就看screen_custom_title.xml,里面有一個title_container和一個content,組合成了標題欄,我們自定義標題所給出的view,都被content作為子view了,影響不了那個title_container和content,所以,任你怎么弄,它該留白的還是留白,你沒招。 看title_container有個style是這樣的:style="?android:attr/windowTitleBackgroundStyle" content的foreground是這樣的android:foreground="?android:attr/windowContentOverlay" 好,從這里我們就可以入手改了。 去values下面的themes.xml找到windowTitleBackgroundStyle這一項,這個應該在注釋<!-- Window attributes -->的下面。 <item name="windowTitleBackgroundStyle">@android:style/WindowTitleBackground</item> <style name="WindowTitleBackground"> <item name="android:background">@android:drawable/title_bar</item> </style>
若修改標題欄高度,請修改android:windowTitleSize
20、關於一個界面中中間使用了scrollView布局后,如果該布局內的控件太長,導致該布局下面的控件無法顯示的問題。
答:網上說個下面這個布局設置一個topmargin為 -xx(負的xx),scrollview的bottommargin為xx 其實最簡單的只需吧scrollview布局的權重設置為1.0就ok了。默認權重為0.0
21.加載對話框動畫效果問題? 答:在日常開發中我們可能會使用動畫效果的ProgressDialog.
比如用戶登陸模塊中,點擊登陸,會彈出對話框。但是如果輸入用戶信息返回錯誤,我們重新輸入后點擊動畫時發現 動畫效果的對話框沒有動畫效果了。 dialog常用的幾個方法:show,dismiss,hide。以及cancel。
一般我在網絡請求的時候show,然后網絡結束后dismiss。此刻我如果出現上訴情況再次請求,動畫效果就不會動了。
可以在dialog.dismiss時改成dialog.hide。兩種方式區別是,前者是調用了是調用了對話框本身的onstop方法,並且從activity上remove去了。
后者是任然掛載在activity,只是隱藏了。動畫線程還在運行,前者估計動畫線程停止了(猜的)
hide后再次show,動畫還是轉的。此刻又會出現一個問題。activity退出時,會報問題18.的leaked Window。因為此刻的dialog還是掛載在activity上。
因此需要在activity中ondestroy中dialog.cancel();