Android培訓之企業(yè)面試官招聘Android開發(fā)者40問答案(上)
2016-03-17 15:31:09
1342瀏覽
在上一篇文章Android培訓之企業(yè)面試官招聘Android開發(fā)者常見40面試題中我們整理了Android開發(fā)者常見的一些面試問題,接下來我們整理了40問的答案。

Android培訓之企業(yè)面試官招聘Android開發(fā)者40問答案(上)
1、 Android的四大組件是哪些,它們的作用?
答:Activity:Activity是
Android程序與用戶交互的窗口,是
Android構造塊中最基本的一種,它需要為保持各界面的狀態(tài),做很多持久化的事情,妥善管理生命周期以及一些跳轉邏輯
service:后臺服務于Activity,封裝有一個完整的功能邏輯實現(xiàn),接受上層指令,完成相關的食物,定義好需要接受的Intent提供同步和異步的接口
Content Provider:是
Android提供的第三方應用數(shù)據(jù)的訪問方案,可以派生Content Provider類,對外提供數(shù)據(jù),可以像數(shù)據(jù)庫一樣進行選擇排序,屏蔽內(nèi)部數(shù)據(jù)的存儲細節(jié),向外提供統(tǒng)一的借口模型,大大簡化上層應用,對數(shù)據(jù)的整合提供了更方便的途徑
BroadCast Receiver:接受一種或者多種Intent作觸發(fā)事件,接受相關消息,做一些簡單處理,轉換成一條Notification,統(tǒng)一了
Android的事件
廣播模型
2、 請介紹下
Android中常用的五種布局。
常用五種布局方式,分別是:FrameLayout(框架布局),LinearLayout (線性布局),AbsoluteLayout(絕對布局),RelativeLayout(相對布局),TableLayout(表格布局)。
一、FrameLayout:所有東西依次都放在左上角,會重疊,這個布局比較簡單,也只能放一點比較簡單的東西。二、LinearLayout:線性布局,每一個
LinearLayout里面又可分為垂直布局(
android:orientation="vertical")和水平布局(
android:orientation="horizontal" )。當垂直布局時,每一行就只有一個元素,多個元素依次垂直往下;水平布局時,只有一行,每一個元素依次向右排列。三、AbsoluteLayout:絕對布局用X,Y坐標來指定元素的位置,這種布局方式也比較簡單,但是在屏幕旋轉時,往往會出問題,而且多個元素的時候,計算比較麻煩。四、RelativeLayout:相對布局可以理解為某一個元素為參照物,
來定位的布局方式。主要屬性有:相對于某一個元素
android:layout_below、
android:layout_toLeftOf相對于父元素的地方
android:layout_alignParentLeft、
android:layout_alignParentRigh;五、TableLayout:表格布局,每一個TableLayout里面有表格行TableRow,TableRow里面可以具體定義每一個元素。每一個布局都有自己適合的方式,這五個布局元素可以相互嵌套應用,做出美觀的界面。
3、
android中的動畫有哪幾類,它們的特點和區(qū)別是什么
答:兩種,一種是Tween動畫、還有一種是Frame動畫。Tween動畫,這種實現(xiàn)方式可以使視圖組件移動、放大、縮小以及產(chǎn)生透明度的變化;另一種Frame動畫,傳統(tǒng)的動畫方法,通過順序的播放排列好的圖片來實現(xiàn),類似電影。
4、
android 中有哪幾種解析xml的類?官方推薦哪種?以及它們的原理和區(qū)別。
答:XML解析主要有三種方式,SAX、DOM、PULL。常規(guī)在PC上開發(fā)我們使用Dom相對輕松些,但一些性能敏感的數(shù)據(jù)庫或手機上還是主要采用SAX方式,SAX讀取是單向的,優(yōu)點:不占內(nèi)存空間、解析屬性方便,但缺點就是對于套嵌多個分支來說處理不是很方便。而DOM方式會把整個XML文件加載到內(nèi)存中去,這里
Android開發(fā)網(wǎng)提醒大家該方法在查找方面可以和XPath很好的結合如果數(shù)據(jù)量不是很大推薦使用,而PULL常常用在J2ME對于節(jié)點處理比較好,類似SAX方式,
同樣很節(jié)省內(nèi)存,在J2ME中我們經(jīng)常使用的KXML庫來解析。
5、 ListView的優(yōu)化方案
答:1、如果自定義適配器,那么在getView方法中要考慮方法傳進來的參數(shù)contentView是否為null,如果為null就創(chuàng)建contentView并返回,如果不為null則直接使用。在這個方法中盡可能少創(chuàng)建view。
2、給contentView設置tag(setTag()),傳入一個viewHolder對象,用于緩存要顯示的數(shù)據(jù),可以達到圖像數(shù)據(jù)異步加載的效果。
3、如果listview需要顯示的item很多,就要考慮分頁加載。比如一共要顯示100條或者更多的時候,我們可以考慮先加載20條,等用戶拉到列表底部的時候再去加載接下來的20條。
6、 請介紹下
Android的數(shù)據(jù)存儲方式。
答:使用SharedPreferences存儲數(shù)據(jù);文件存儲數(shù)據(jù);SQLite數(shù)據(jù)庫存儲數(shù)據(jù);使用ContentProvider存儲數(shù)據(jù);網(wǎng)絡存儲數(shù)據(jù);
Preference,F(xiàn)ile, DataBase這三種方式分別對應的目錄是
/data/data/Package Name/Shared_Pref, /data/data/Package Name/files, /data/data/Package Name/database 。
一:使用SharedPreferences存儲數(shù)據(jù)
首先說明SharedPreferences存儲方式,它是
Android提供的用來存儲一些簡單配置信息的一種機制,例如:登錄用戶的用戶名與密碼。其采用了Map數(shù)據(jù)結構來存儲數(shù)據(jù),以鍵值的方式存儲,可以簡單的讀取與寫入,具體實例如下: void ReadSharedPreferences(){
String strName,strPassword;
SharedPreferences user = getSharedPreferences(“user_info”,0); strName = user.getString(“NAME”,””);
strPassword = user getString(“PASSWORD”,””);
}
void WriteSharedPreferences(String strName,String strPassword){ SharedPreferences user = getSharedPreferences(“user_info”,0); uer.edit();
user.putString(“NAME”, strName);
user.putString(“PASSWORD” ,strPassword);
user.commit();
}
數(shù)據(jù)讀取與寫入的方法都非常簡單,只是在寫入的時候有些區(qū)別:先調(diào)用edit()使其處于編輯狀態(tài),然后才能修改數(shù)據(jù),最后使用commit()提交修改的數(shù)據(jù)。實際上SharedPreferences是采用了XML格式將數(shù)據(jù)存儲到設備中,在DDMS中的File Explorer中的/data/data/<package name>/shares_prefs下。使用SharedPreferences是有些限制的:只能在同一個包內(nèi)使用,不能在不同的包之間使用。
二:文件存儲數(shù)據(jù)
文件存儲方式是一種較常用的方法,在
Android中讀取/寫入文件的方法,與 Java中實現(xiàn)I/O的程序是完全一樣的,提供了openFileInput()和
openFileOutput()方法來讀取設備上的文件。具體實例如下:
String fn = “mo
android.log”;
徑,返回匹配碼為1
uriMatcher.addURI(“com.changcheng.sqlite.provider.contactprovider”, “contact”, 1);//添加需要匹配uri,如果匹配就會返回匹配碼
//如果match()方法匹配
content://com.changcheng.sqlite.provider.contactprovider/contact/230路徑,返回匹配碼為2
uriMatcher.addURI(“com.changcheng.sqlite.provider.contactprovider”, “contact/#”, 2);//#號為通配符
2.注冊完需要匹配的Uri后,就可以使用uriMatcher.match(uri)方法對輸入的Uri進行匹配,如果匹配就返回匹配碼,匹配碼是調(diào)用 addURI()方法傳入的第三個參數(shù),假設匹配
content://com.changcheng.sqlite.provider.contactprovider/contact路徑,返回的匹配碼為1。
ContentUris:用于獲取Uri路徑后面的ID部分,它有兩個比較實用的方法: withAppendedId(uri, id)用于為路徑加上ID部分
parseId(uri)方法用于從路徑中獲取ID部分
ContentResolver:當外部應用需要對ContentProvider中的數(shù)據(jù)進行添加、刪除、修改和查詢操作時,可以使用 ContentResolver 類來完成,要獲取
ContentResolver 對象,可以使用Activity提供的getContentResolver()方法。 ContentResolver使用insert、delete、update、query方法,來操作數(shù)據(jù)。
7、 activity的啟動模式有哪些?是什么含義?
答:在
android里,有4種activity的啟動模式,分別為:
“standard” (默認)
“singleTop”
“singleTask”
“singleInstance”
它們主要有如下不同:
1. 如何決定所屬task
“standard”和”singleTop”的activity的目標task,和收到的Intent的發(fā)送者在同一個task內(nèi),除非intent包括參數(shù)FLAG_ACTIVITY_NEW_TASK。 如果提供了FLAG_ACTIVITY_NEW_TASK參數(shù),會啟動到別的task里。
“singleTask”和”singleInstance”總是把activity作為一個task的根元素,他們不會被啟動到一個其他task里。
2. 是否允許多個實例
“standard”和”singleTop”可以被實例化多次,并且存在于不同的task中,且一個task可以包括一個activity的多個實例;
“singleTask”和”singleInstance”則限制只生成一個實例,并且是task的根元素。 singleTop要求如果創(chuàng)建intent的時候棧頂已經(jīng)有要創(chuàng)建 的Activity的實例,則將intent發(fā)送給該實例,而不發(fā)送給新的實例。
3. 是否允許其它activity存在于本task內(nèi)
“singleInstance”獨占一個task,其它activity不能存在那個task里;如果它啟動了一個新的activity,不管新的activity的launch mode 如何,新的activity都將會到別的task里運行(如同加了FLAG_ACTIVITY_NEW_TASK參數(shù))。
而另外三種模式,則可以和其它activity共存。
4. 是否每次都生成新實例
“standard”對于沒一個啟動Intent都會生成一個activity的新實例; “singleTop”的activity如果在task的棧頂?shù)脑?,則不生成新的該activity的實例,直接使用棧頂?shù)膶嵗?,否則,生成該activity的實例。
比如現(xiàn)在task棧元素為A-B-C-D(D在棧頂),這時候給D發(fā)一個啟動intent,如果D是 “standard”的,則生成D的一個新實例,棧變?yōu)锳-B-C-D-D。 如果D是singleTop的話,則不會生產(chǎn)D的新實例,棧狀態(tài)仍為A-B-C-D 如果這時候給B發(fā)Intent的話,不管B的launchmode是”standard” 還是 “singleTop” ,都會生成B的新實例,棧狀態(tài)變?yōu)锳-B-C-D-B。
“singleInstance”是其所在棧的唯一activity,它會每次都被重用。
“singleTask”如果在棧頂,則接受intent,否則,該intent會被丟棄,但是該task仍會回到前臺。
當已經(jīng)存在的activity實例處理新的intent時候,會調(diào)用onNewIntent()方法 如果收到intent生成一個activity實例,那么用戶可以通過back鍵回到上一個狀態(tài);如果是已經(jīng)存在的一個activity來處理這個intent的話,用戶不能通過按back鍵返回到這之前的狀態(tài)。
8、 跟activity和Task 有關的 Intent啟動方式有哪些?其含義?
核心的Intent Flag有:
FLAG_ACTIVITY_NEW_TASK
FLAG_ACTIVITY_CLEAR_TOP
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
FLAG_ACTIVITY_SINGLE_TOP
FLAG_ACTIVITY_NEW_TASK
如果設置,這個Activity會成為歷史stack中一個新Task的開始。一個Task(從啟動它的Activity到下一個Task中的 Activity)定義了用戶可以遷移的Activity原子組。Task可以移動到前臺和后臺;在某個特定Task中的所有Activity總是保持相同的次序。
這個標志一般用于呈現(xiàn)“啟動”類型的行為:它們提供用戶一系列可以單獨完成的事情,與啟動它們的Activity完全無關。
使用這個標志,如果正在啟動的Activity的Task已經(jīng)在運行的話,那么,新的Activity將不會啟動;代替的,當前Task會簡單的移入前臺。參考FLAG_ACTIVITY_MULTIPLE_TASK標志,可以禁用這一行為。
這個標志不能用于調(diào)用方對已經(jīng)啟動的Activity請求結果。
FLAG_ACTIVITY_CLEAR_TOP
如果設置,并且這個Activity已經(jīng)在當前的Task中運行,因此,不再是重新啟動一個這個Activity的實例,而是在這個Activity上方的所有Activity都將關閉,然后這個Intent會作為一個新的Intent投遞到老的Activity(現(xiàn)在位于頂端)中。
例如,假設一個Task中包含這些Activity:A,B,C,D。如果D調(diào)用了startActivity(),并且包含一個指向Activity B的Intent,那么,C和D都將結束,然后B接收到這個Intent,因此,目前stack的狀況是:A,B。 上例中正在運行的Activity B既可以在onNewIntent()中接收到這個新的Intent,也可以把自己關閉然后重新啟動來接收這個Intent。如果它的啟動模
式聲明為 “multiple”(默認值),并且你沒有在這個Intent中設置
FLAG_ACTIVITY_SINGLE_TOP標志,那么它將關閉然后重新創(chuàng)建;對于其它的啟動模式,或者在這個Intent中設置FLAG_ACTIVITY_SINGLE_TOP標志,都將把這個Intent投遞到當前這個實例的onNewIntent()中。
這個啟動模式還可以與FLAG_ACTIVITY_NEW_TASK結合起來使用:用于啟動一個Task中的根Activity,它會把那個Task中任何運行的實例帶入前臺,然后清除它直到根Activity。這非常有用,例如,當從Notification Manager處啟動一個Activity。
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
如果設置這個標志,這個activity不管是從一個新的棧啟動還是從已有棧推到棧頂,它都將以the front door of the task的方式啟動。這就講導致任何與應用相關的棧都講重置到正常狀態(tài)(不管是正在講activity移入還是移除),如果需要,或者直接重置該棧為初始狀態(tài)。
FLAG_ACTIVITY_SINGLE_TOP
如果設置,當這個Activity位于歷史stack的頂端運行時,不再啟動一個新的
FLAG_ACTIVITY_BROUGHT_TO_FRONT
這個標志一般不是由程序代碼設置的,如在launchMode中設置singleTask模式時系統(tǒng)幫你設定。
FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
如果設置,這將在Task的Activity stack中設置一個還原點,當Task恢復時,需要清理Activity。也就是說,下一次Task帶著
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED標記進入前臺時(典型的操作是用戶在主畫面重啟它),這個Activity和它之上的都將關閉,以至于用戶不能再返回到它們,但是可以回到之前的Activity。
這在你的程序有分割點的時候很有用。例如,一個e-mail應用程序可能有一個操作是查看一個附件,需要啟動圖片瀏覽Activity來顯示。這個 Activity應該作為e-mail應用程序Task的一部分,因為這是用戶在這個Task中觸發(fā)的操作。然而,當用戶離開這個Task,然后從主畫面選擇e-mail app,我們可能希望回到查看的會話中,但不是查看圖片附件,因為這讓人困惑。通過在啟動圖片瀏覽時設定這個標志,瀏覽及其它啟動的Activity在下次用戶返回到mail程序時都將全部清除。
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
如果設置,新的Activity不會在最近啟動的Activity的列表中保存。 FLAG_ACTIVITY_FORWARD_RESULT
如果設置,并且這個Intent用于從一個存在的Activity啟動一個新的Activity,那么,這個作為答復目標的Activity將會傳到這個新的Activity中。這種方式下,新的Activity可以調(diào)用setResult(int),并且這個結果值將發(fā)送給那個作為答復目標的 Activity。
FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
這個標志一般不由應用程序代碼設置,如果這個Activity是從歷史記錄里啟動的(常按HOME鍵),那么,系統(tǒng)會幫你設定。
FLAG_ACTIVITY_MULTIPLE_TASK
不要使用這個標志,除非你自己實現(xiàn)了應用程序啟動器。與
FLAG_ACTIVITY_NEW_TASK結合起來使用,可以禁用把已存的Task送入前臺的行為。當設置時,新的Task總是會啟動來處理Intent,而不管這是是否已經(jīng)有一個Task可以處理相同的事情。
由于默認的系統(tǒng)不包含圖形Task管理功能,因此,你不應該使用這個標志,除非你提供給用戶一種方式可以返回到已經(jīng)啟動的Task。
如果FLAG_ACTIVITY_NEW_TASK標志沒有設置,這個標志被忽略。
FLAG_ACTIVITY_NO_ANIMATION
如果在Intent中設置,并傳遞給Context.startActivity()的話,這個標志將阻止系統(tǒng)進入下一個Activity時應用 Acitivity遷移動畫。這并不意味著動畫將永不運行——如果另一個Activity在啟動顯示之前,沒有指定這個標志,那么,動畫將被應用。這個標志可以很好的用于執(zhí)行一連串的操作,而動畫被看作是更高一級的事件的驅動。
FLAG_ACTIVITY_NO_HISTORY
如果設置,新的Activity將不再歷史stack中保留。用戶一離開它,這個Activity就關閉了。這也可以通過設置noHistory特性。
FLAG_ACTIVITY_NO_USER_ACTION
如果設置,作為新啟動的Activity進入前臺時,這個標志將在Activity暫停之前阻止從最前方的Activity回調(diào)的onUserLeaveHint()。
典型的,一個Activity可以依賴這個回調(diào)指明顯式的用戶動作引起的
Activity移出后臺。這個回調(diào)在Activity的生命周期中標記一個合適的點,并關閉一些Notification。
如果一個Activity通過非用戶驅動的事件,如來電或鬧鐘,啟動的,這個標志也應該傳遞給Context.startActivity,保證暫停的Activity不認為用戶已經(jīng)知曉其Notification。
FLAG_ACTIVITY_PREVIOUS_IS_TOP
If set and this intent is being used to launch a new activity from an existing one, the current activity will not be counted as the top activity for deciding whether the new intent should be delivered to the top instead of starting a new one. The previous activity will be used as the top, with the assumption being that the current activity will finish itself immediately.
FLAG_ACTIVITY_REORDER_TO_FRONT
如果在Intent中設置,并傳遞給Context.startActivity(),這個標志將引發(fā)已經(jīng)運行的Activity移動到歷史stack的頂端。
例如,假設一個Task由四個Activity組成:A,B,C,D。如果D調(diào)用
startActivity()來啟動Activity B,那么,B會移動到歷史stack的頂端,現(xiàn)在的次序變成A,C,D,B。如果FLAG_ACTIVITY_CLEAR_TOP標志也設置的話,那么這個標志將被忽略。
9、 請描述下Activity的生命周期。
答:activity的生命周期方法有:onCreate()、onStart()、onReStart()、onResume()、onPause()、onStop()、onDestory();
可見生命周期:從onStart()直到系統(tǒng)調(diào)用onStop()
前臺生命周期:從onResume()直到系統(tǒng)調(diào)用onPause()
法在調(diào)用者與服務綁定時被調(diào)用,當調(diào)用者與服務已經(jīng)綁定,多次調(diào)用Context.bindService()方法并不會導致該方法被多次調(diào)用。
onUnbind()只有采用Context.bindService()方法啟動服務時才會回調(diào)該方法。該方法在調(diào)用者與服務解除綁定時被調(diào)用
12、 注冊廣播有幾種方式,這些方式有何優(yōu)缺點?請談談
Android引入廣播機制的用意。
答:首先寫一個類要繼承BroadcastReceiver
第一種:在清單文件中聲明,添加
<receive
android:name=".IncomingSMSReceiver " >
<intent-filter>
<action
android:name="
android.provider.Telephony.SMS_RECEIVED") <intent-filter>
<receiver>
第二種使用代碼進行注冊如:
IntentFilter filter = new
IntentFilter("
android.provider.Telephony.SMS_RECEIVED");
IncomingSMSReceiver receiver = new IncomgSMSReceiver();
registerReceiver(receiver.filter);
兩種注冊類型的區(qū)別是:
1)第一種不是常駐型廣播,也就是說廣播跟隨程序的生命周期。
2)第二種是常駐型,也就是說當應用程序關閉后,如果有信息廣播來,程序也會被系統(tǒng)調(diào)用自動運行。
13、 請解釋下在單線程模型中Message、Handler、Message Queue、Looper之間的關系。
答:簡單的說,Handler獲取當前線程中的looper對象,looper用來從存放Message的MessageQueue中取出Message,再有Handler進行Message的分發(fā)和處理.
Message Queue(消息隊列):用來存放通過Handler發(fā)布的消息,通常附屬于某一個創(chuàng)建它的線程,可以通過Looper.myQueue()得到當前線程的消息隊列 Handler:可以發(fā)布或者處理一個消息或者操作一個Runnable,通過Handler發(fā)布消息,消息將只會發(fā)送到與它關聯(lián)的消息隊列,然也只能處理該消息隊列中的消息
Looper:是Handler和消息隊列之間通訊橋梁,程序組件首先通過Handler把消息傳遞給Looper,Looper把消息放入隊列。Looper也把消息隊列里的消息廣播給所有的
Handler:Handler接受到消息后調(diào)用handleMessage進行處理
Message:消息的類型,在Handler類中的handleMessage方法中得到單個的消息進行處理
在單線程模型下,為了線程通信問題,
Android設計了一個Message Queue(消息隊列), 線程間可以通過該Message Queue并結合Handler和Looper組件進行信息交換。下面將對它們進行分別介紹:
1. Message
Message消息,理解為線程間交流的信息,處理數(shù)據(jù)后臺線程需要更新UI,則發(fā)送Message內(nèi)含一些數(shù)據(jù)給UI線程。
2. Handler
Handler處理者,是Message的主要處理者,負責Message的發(fā)送,Message內(nèi)容的執(zhí)行處理。后臺線程就是通過傳進來的 Handler對象引用來
sendMessage(Message)。而使用Handler,需要implement 該類的
handleMessage(Message)方法,它是處理這些Message的操作內(nèi)容,例如Update UI。通常需要子類化Handler來實現(xiàn)handleMessage方法。
3. Message Queue
Message Queue消息隊列,用來存放通過Handler發(fā)布的消息,按照先進先出執(zhí)行。
每個message queue都會有一個對應的Handler。Handler會向message queue通過兩種方法發(fā)送消息:sendMessage或post。這兩種消息都會插在message queue隊尾并按先進先出執(zhí)行。但通過這兩種方法發(fā)送的消息執(zhí)行的方式略有不同:通過sendMessage發(fā)送的是一個message對象,會被 Handler的handleMessage()函數(shù)處理;而通過post方法發(fā)送的是一個runnable對象,則會自己執(zhí)行。
4. Looper
Looper是每條線程里的Message Queue的管家。
Android沒有Global的Message Queue,而
Android會自動替主線程(UI線程)建立Message Queue,但在子線程里并沒有建立Message Queue。所以調(diào)用Looper.getMainLooper()得到的主線程的Looper不為NULL,但調(diào)用Looper.myLooper() 得到當前線程的Looper就有可能為NULL。對于子線程使用Looper,API Doc提供了正確的使用方法:這個Message機制的大概流程:
1. 在Looper.loop()方法運行開始后,循環(huán)地按照接收順序取出Message Queue里面的非NULL的Message。
2. 一開始Message Queue里面的Message都是NULL的。當
Handler.sendMessage(Message)到Message Queue,該函數(shù)里面設置了那個Message對象的target屬性是當前的Handler對象。隨后Looper取出了那個Message,則調(diào)用 該Message的target指向的Hander的dispatchMessage函數(shù)對Message進行處理。在dispatchMessage方法里,如何處理Message則由用戶指定,三個判斷,優(yōu)先級從高到低:
1) Message里面的Callback,一個實現(xiàn)了Runnable接口的對象,其中run函數(shù)做處理工作;
2) Handler里面的mCallback指向的一個實現(xiàn)了Callback接口的對象,由其handleMessage進行處理;
3) 處理消息Handler對象對應的類繼承并實現(xiàn)了其中handleMessage函數(shù),通過這個實現(xiàn)的handleMessage函數(shù)處理消息。
由此可見,我們實現(xiàn)的handleMessage方法是優(yōu)先級最低的!
3. Handler處理完該Message (update UI) 后,Looper則設置該Message為NULL,以便回收!
在網(wǎng)上有很多文章講述主線程和其他子線程如何交互,傳送信息,最終誰來執(zhí)行處理信息之類的,個人理解是最簡單的方法——判斷Handler對象里面的Looper對象是屬于哪條線程的,則由該線程來執(zhí)行!
1. 當Handler對象的構造函數(shù)的參數(shù)為空,則為當前所在線程的Looper;
2. Looper.getMainLooper()得到的是主線程的Looper對象,
Looper.myLooper()得到的是當前線程的Looper對象。
14、 簡要解釋一下activity、 intent 、intent filter、service、Broadcase、BroadcaseReceiver
答:一個activity呈現(xiàn)了一個用戶可以操作的可視化用戶界面;一個service不包含可見的用戶界面,而是在后臺運行,可以與一個activity綁定,通過綁定暴露出來接口并與其進行通信;一個broadcast receiver是一個接收廣播消息并做出回應的component,broadcast receiver沒有界面;一個intent是一個Intent對象,它保存了消息的內(nèi)容。對于activity和service來說,它指定了請求的操作名稱和待操作數(shù)據(jù)的URI,Intent對象可以顯式的指定一個目標component。如果這樣的話,
android會找到這個component(基于manifest文件中的聲明)并激活它。但如果一個目標不是顯式指定的,
android必須找到響應intent的最佳component。它是通過將Intent對象和目標的intent filter相比較來完成這一工作的;一個component的intent filter告訴
android該component能處理的intent。intent filter也是在manifest文件中聲明的。
15、 說說mvc模式的原理,它在
android中的運用,
android的官方建議應用程序的開發(fā)采用mvc模式。何謂mvc?
mvc是model,view,controller的縮寫,mvc包含三個部分:
模型(model)對象:是應用程序的主體部分,所有的業(yè)務邏輯都應該寫在該層。
視圖(view)對象:是應用程序中負責生成用戶界面的部分。也是在整個mvc架構中用戶唯一可以看到的一層,接收用戶的輸入,顯示處理結果。
控制器(control)對象:是根據(jù)用戶的輸入,控制用戶界面數(shù)據(jù)顯示及更新model對象狀態(tài)的部分,控制器更重要的一種導航功能,響應用戶出發(fā)的相關事件,交給m層處理。
android鼓勵弱耦合和組件的重用,在
android中mvc的具體體現(xiàn)如下:
1)視圖層(view):一般采用xml文件進行界面的描述,使用的時候可以非常方便的引入,當然,如果你對
android了解的比較的多了話,就一定可以想到在
android中也可以使用javascript+html等的方式作為view層,當然這里需要進行java和javascript之間的通信,幸運的是,
android提供了它們之間非常方便的通信實現(xiàn)。
2)控制層(controller):
android的控制層的重任通常落在了眾多的acitvity的肩上,這句話也就暗含了不要在acitivity中寫代碼,要通過activity交割model業(yè)務邏輯層處理,這樣做的另外一個原因是
android中的acitivity的響應時間是5s,如果耗時的操作放在這里,程序就很容易被回收掉。
3)模型層(model):對數(shù)據(jù)庫的操作、對網(wǎng)絡等的操作都應該在model里面處理,當然對業(yè)務計算等操作也是必須放在的該層的。
16、 什么是ANR 如何避免它?
答:ANR:Application Not Responding。在
Android中,活動管理器和窗口管理器這兩個系統(tǒng)服務負責監(jiān)視應用程序的響應,當用戶操作的在5s內(nèi)應用程序沒能做出反應,BroadcastReceiver在10秒內(nèi)沒有執(zhí)行完畢,就會出現(xiàn)應用程序無響應對話框,這既是ANR。
避免方法:Activity應該在它的關鍵生命周期方法(如onCreate()和
onResume())里盡可能少的去做創(chuàng)建操作。潛在的耗時操作,例如網(wǎng)絡或數(shù)據(jù)庫操作,或者高耗時的計算如改變位圖尺寸,應該在子線程里(或者異步方式)來完成。主線程應該為子線程提供一個Handler,以便完成時能夠提交給主線程。
17、 什么情況會導致Force Close ?如何避免?能否捕獲導致其的異常? 答:程序出現(xiàn)異常,比如nullpointer。
避免:編寫程序時邏輯連貫,思維縝密。能捕獲異常,在logcat中能看到異常信息
18、 描述一下
android的系統(tǒng)架構
android系統(tǒng)架構分從下往上為linux 內(nèi)核層、運行庫、應用程序框架層、和應用程序層。
linuxkernel:負責硬件的驅動程序、網(wǎng)絡、電源、系統(tǒng)安全以及內(nèi)存管理等功能。
libraries和
android runtime:libraries:即c/c++函數(shù)庫部分,大多數(shù)都是開放源代碼的函數(shù)庫,例如webkit(引擎),該函數(shù)庫負責
android網(wǎng)頁瀏覽器的運行,例如標準的c函數(shù)庫libc、openssl、sqlite等,當然也包括支持游戲開發(fā)2dsgl和 3dopengles,在多媒體方面有mediaframework框架來支持各種影音和圖形文件的播放與顯示,例如mpeg4、h.264、mp3、 aac、amr、jpg和png等眾多的多媒體文件格式。
android的runtime負責解釋和執(zhí)行生成的dalvik格式的字節(jié)碼。
applicationframework(應用軟件架構),java應用程序開發(fā)人員主要是使用該層封裝好的api進行快速開發(fā)。
applications:該層是java的應用程序層,
android內(nèi)置的googlemaps、e-mail、即時通信工具、瀏覽器、mp3播放器等處于該層,java開發(fā)人員開發(fā)的程序也處于該層,而且和內(nèi)置的應用程序具有平等的位置,可以調(diào)用內(nèi)置的應用程序,也可以替換內(nèi)置的應用程序。
上面的四個層次,下層為上層服務,上層需要下層的支持,調(diào)用下層的服務,這種嚴格分層的方式帶來的極大的穩(wěn)定性、靈活性和可擴展性,使得不同層的開發(fā)人員可以按照規(guī)范專心特定層的開發(fā)。
android應用程序使用框架的api并在框架下運行,這就帶來了程序開發(fā)的高度一致性,另一方面也告訴我們,要想寫出優(yōu)質高效的程序就必須對整個 applicationframework進行非常深入的理解。精通applicationframework,你就可以真正的理解
android的設計和運行機制,也就更能夠駕馭整個應用層的開發(fā)。
19、 請介紹下ContentProvider是如何實現(xiàn)數(shù)據(jù)共享的。
一個程序可以通過實現(xiàn)一個Content provider的抽象接口將自己的數(shù)據(jù)完全暴露出去,而且Content providers是以類似數(shù)據(jù)庫中表的方式將數(shù)據(jù)暴露。Content providers存儲和檢索數(shù)據(jù),通過它可以讓所有的應用程序訪問到,這也是應用程序之間唯一共享數(shù)據(jù)的方法。
要想使應用程序的數(shù)據(jù)公開化,可通過2種方法:創(chuàng)建一個屬于你自己的Content provider或者將你的數(shù)據(jù)添加到一個已經(jīng)存在的Content provider中,前提是有相同數(shù)據(jù)類型并且有寫入Content provider的權限。
如何通過一套標準及統(tǒng)一的接口獲取其他應用程序暴露的數(shù)據(jù)?
Android提供了ContentResolver,外界的程序可以通過ContentResolver接口訪問ContentProvider提供的數(shù)據(jù)。
查看更多關于“Android培訓資訊”的相關文章>>
標簽: