標籤:
1、Android的四大組件是哪些,它們的作用?
ActivityActivity是Android程式與使用者互動的視窗,是Android構造塊中最基本的一種,它需要為保持各介面的狀態,做很多持久化的事情,妥善管理生命週期以及一些跳轉邏輯。
Service後台服務於Activity,封裝有一個完整的功能邏輯實現,接受上層指令,完成相關的食物,定義好需要接受的Intent提供同步和非同步介面。
Content Provider是Android提供的第三方應用資料的訪問方案,可以派生Content Provider類,對外提供資料,可以像資料庫一樣進行選擇排序,屏蔽內部資料的儲存細節,向外提供統一的借口模型,大大簡化上層應用,對資料的整合提供了更方便的途徑
BroadCast Receiver接受一種或者多種Intent作觸發事件,接受相關訊息,做一些簡單處理,轉換成一條Notification,統一了Android的事件廣播模型。
2、請介紹下Android中常用的五種布局
FrameLayout(架構布局)
所有東西依次都放在左上方,會重疊,這個布局比較簡單,也只能放一點比較簡單的東西。
LinearLayout (線性布局)
線性布局,每一個LinearLayout裡面又可分為垂直布局(android:orientation=”vertical”)和水平布局(android:orientation=”horizontal” )。當垂直布局時,每一行就只有一個元素,多個元素依次垂直往下;水平布局時,只有一行,每一個元素依次向右排列。
RelativeLayout(相對布局)
相對布局可以理解為某一個元素為參照物,來定位的布局方式。主要屬性有:相對於某一個元素android:layout_below、android:layout_toLeftOf相對於父元素的地方android:layout_alignParentLeft
android:layout_alignParentRigh;
TableLayout(表格版面配置)
表格版面配置,每一個TableLayout裡面有表格行TableRow,TableRow裡面可以具體定義每一個元素。
AbsoluteLayout(絕對布局)
絕對布局用X,Y座標來指定元素的位置,這種布局方式也比較簡單,但是在旋轉螢幕時,往往會出問題,而且多個元素的時候,計算比較麻煩。
3、Activity的生命週期?
Oncreate:在Activity對象被第一次建立時調用
OnStart:當Activity變得可見時調用該函數
OnResume:當Activity開始,準備與使用者互動時調用該方法
Onpause:當系統即將啟動另外一個Activity之前調用的方法
Onstop:當前Activity變得不可見時調用該方法。
OnDestroy:當前Activity被銷毀之前將會調用該方法
OnRestart:當一個Activity再次啟動之前將會調用該方法
Main:OnCreate( )->OnStart( )->OnResume( )
點擊按鈕到另外一個Activity
Main:Onpause( )
Other:OnCreate( )->OnStart( )->OnResume( )
Main:Onstop( )
返回
Other:Onpause( )
Main:OnRestart( )->OnStart( )->OnResume( )
Other:Onstop( )->OnDestroy( )
4、android中的動畫有哪幾類,它們的特點和區別是什嗎?
兩種,一種是Tween動畫、還有一種是Frame動畫。Tween動畫,這種實現方式可以使視圖組件移動、放大、縮小以及產生透明度的變化;另一種Frame動畫,傳統的動畫方法,通過順序的播放排列好的圖片來實現,類似電影。
5、android 中有哪幾種解析xml的類?官方推薦哪種?以及它們的原理和區別。
XML解析主要有三種方式,SAX、DOM、PULL。
常規在PC上開發我們使用Dom相對輕鬆些,但一些效能敏感的資料庫或手機上還是主要採用SAX方式,SAX讀取是單向的,優點:不佔記憶體空間、解析屬性方便,但缺點就是對於套嵌多個分支來說處理不是很方便。而DOM方式會把整個XML檔案載入到記憶體中去,這裡Android開發網提醒大家該方法在尋找方面可以和XPath很好的結合如果資料量不是很大推薦使用,而PULL常常用在J2ME對於節點處理比較好,類似SAX方式,同樣很節省記憶體,在J2ME中我們經常使用的KXML庫來解析。
6、說說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裡面處理,當然對業務計算等操作也是必須放在的該層的。
7、請解釋下在單執行緒模式中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會向message queue通過兩種方法發送訊息:sendMessage或post。這兩種訊息都會插在message queue隊尾並按先進先出執行。但通過這兩種方法發送的訊息執行的方式略有不同:通過sendMessage發送的是一個message對象,會被 Handler的handleMessage()函數處理;而通過post方法發送的是一個runnable對象,則會自己執行。
4. Looper
Looper是每條線程裡的Message Queue的管家。Android沒有Global的Message Queue,而Android會自動替主線程(UI線程)建立Message Queue,但在子線程裡並沒有建立Message Queue。所以調用Looper.getMainLooper()得到的主線程的Looper不為NULL,但調用Looper.myLooper() 得到當前線程的Looper就有可能為NULL。對於子線程使用Looper,API Doc提供了正確的使用方法:這個Message機制的大概流程:
1. 在Looper.loop()方法運行開始後,迴圈地按照接收順序取出Message Queue裡面的非NULL的Message。
2. 一開始Message Queue裡面的Message都是NULL的。當Handler.sendMessage(Message)到Message Queue,該函數裡面設定了那個Message對象的target屬性是當前的Handler對象。隨後Looper取出了那個Message,則調用 該Message的target指向的Hander的dispatchMessage函數對Message進行處理。在dispatchMessage方法裡,如何處理Message則由使用者指定,三個判斷,優先順序從高到低:
1) Message裡面的Callback,一個實現了Runnable介面的對象,其中run函數做處理工作;
2) Handler裡面的mCallback指向的一個實現了Callback介面的對象,由其handleMessage進行處理;
3) 處理訊息Handler對象對應的類繼承並實現了其中handleMessage函數,通過這個實現的handleMessage函數處理訊息。
由此可見,我們實現的handleMessage方法是優先順序最低的!
3. Handler處理完該Message (update UI) 後,Looper則設定該Message為NULL,以便回收!
在網上有很多文章講述主線程和其他子線程如何互動,傳送資訊,最終誰來執行處理資訊之類的,個人理解是最簡單的方法——判斷Handler對象裡面的Looper對象是屬於哪條線程的,則由該線程來執行!
1. 當Handler對象的建構函式的參數為空白,則為當前所線上程的Looper;
2. Looper.getMainLooper()得到的是主線程的Looper對象,Looper.myLooper()得到的是當前線程的Looper對象。
Android面試題