其實好多你只要理解大致的意思就行了。解答都是偏長。
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:設計模式上(反轉控制的一種應用,類似監聽者模式)
Spring MVC
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指dalvik的虛擬機。每一個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。
2、給contentView設置tag(setTag()),傳入一個viewHolder對象,用於緩存要顯示的數據,可以達到圖像數據異步加載的效果。
3、如果listview需要顯示的item很多,就要考慮分頁加載。比如一共要顯示100條或者更多的時候,我們可以考慮先加載20條,等用戶拉到列表底部的時候再去加載接下來的20條。
(這個其實還是很有實際意義)。
------------------以下是自己項目或是被問到的幾個問題----------------
15.讓你說出一個自定義控件的流程。
答:這個看你自己,我被問到過一個自定的progressbar。說里面不停轉動的圖片怎么實現。
http://blog.csdn.net/mad1989/article/details/38042875
http://www.open-open.com/lib/view/open1434354750036.html
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標題后背景無法填充完整?
此問題轉次某個論壇的某哥們。我遇到的是背景無法填充完整。
http://www.iteye.com/topic/760314
----- 若修改標題欄高度,請修改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();
1. 請描述一下Activity 生命周期。
答: 如下圖所示。共有七個周期函數,按順序分別是: onCreate(), onStart(), onRestart(), onResume(), onPause(),onStop(), onDestroy()。
onCreate(): 創建Activity時調用,設置在該方法中,還以Bundle的形式提供對以前存儲的任何狀態的訪問。
onStart(): Activity變為在屏幕上對用戶可見時調用。
onResume(): Activity開始與用戶交互時調用(無論是啟動還是重新啟動一個活動,該方法總是被調用。
onPause(): Activity被暫停或收回cpu和其他資源時調用,該方法用戶保護活動狀態的,也是保護現場。
onStop(): Activity被停止並轉為不可見階段及后續的生命周期事件時調用。
onRestart(): Activity被重新啟動時調用。該活動仍然在棧中,而不是啟動新的Activity。
1、完整生命周期: 即從一個Activity從出現到消失,對應的周期方法是從onCreate()到onDestroy()。
2、可見生命周期: 當Activity處於可以用戶看見的狀態,但不一定能與用戶交互時,將多次執行從onStart()到onStop()。
3、前景生命周期: 當Activity處於Activity棧最頂端,能夠與其他用戶進行交互時,將多次執行從onResume()到onPause()。
2. 兩個Activity之間跳轉時必然會執行的是哪幾個方法。
答: 兩個Activity之間跳轉必然會執行的是下面幾個方法。
onCreate()//在Activity生命周期開始時調用。
onRestoreInstanceState()//用來恢復UI狀態。
onRestart()//當Activity重新啟動時調用。
onStart()//當Activity對用戶即將可見時調用。
onResume()//當Activity與用戶交互時,繪制界面。
onSaveInstanceState()//即將移出棧頂保留UI狀態時調用。
onPause()//暫停當前活動Activity,提交持久數據的改變,停止動畫或其他占用GPU資源的東西,由於下一個Activity在這個方法返回之前不會resume,所以這個方法的代碼執行要快。
onStop()//Activity不再可見時調用。
onDestroy()//Activity銷毀棧時被調用的最后一個方法。
3. 橫豎屏切換時候Activity的生命周期。
答:
1、不設置Activity的android: configChanges時,切屏會重新調用各個生命周期,切橫屏時會執行一次,切豎屏時會執行兩次。
2、設置Activity的android: configChanges=“orientation”時,切屏還是會重新調用各個生命周期,切橫、豎屏時只會執行一次。
3、設置Activity的android: configChanges=“orientation|keyboardHidden”時,切屏不會重新調用各個生命周期,只會執行onConfiguration方法
4. 如何將一個Activity設置成窗口的樣式。
答:
第一種方法,在styles.xml文件中,可以新建如下的類似Dialog的style。
<style name=“Theme.FloatActivity” parent=“android:style/Theme.Dialog”> </style>。
第二種方法,在AndroidManifest.xml中在需要顯示為窗口的Activity中添加如下屬性: android: theme=“@style/Theme.FloatActivity”即可。也可以直接添加對應需要展示為Dialog style的Activity的android: theme屬性為android: theme=“@ android: style/Theme.Dialog”。
5. 兩個Activity之間怎么傳遞數據?
答: 可以在Intent對象中利用Extra來傳遞存儲數據。
在Intent的對象請求中,使用putExtra(“鍵值對的名字”,”鍵值對的值”);在另外一個Activity中將Intent中的請求數據取出來:
Intent intent = getIntent();
String value = intent.getStringExtra(“testIntent”);
6. 怎么讓在啟動一個Activity是就啟動一個service?
答: 首先定義好一個service,然后在Activity的onCreate里面進行連接並bindservice或者直接startService。
7. Activity怎么和service綁定,怎么在activity中啟動自己對應的service?
答: 1、activity能進行綁定得益於Serviece的接口。為了支持Service的綁定,實現onBind方法。
2、Service和Activity的連接可以用ServiceConnection來實現。需要實現一個新的ServiceConnection,重現onServiceConnected和OnServiceDisconnected方法,一旦連接建立,就能得到Service實例的引用。
3、執行綁定,調用bindService方法,傳入一個選擇了要綁定的Service的Intent(顯示或隱式)和一個你實現了的ServiceConnection的實例
8.什么是Service以及描述下它的生命周期。Service有哪些啟動方法,有什么區別,怎樣停用Service?
答: Android Service是運行在后台的代碼,不能與用戶交互,可以運行在自己的進程,也可以運行在其他應用程序進程的上下文里。需要通過某一個Activity或者Context對象來調用。Service有兩個啟動方法,分別是Context.startService()和Context.bindService()。如果在Service執行耗時的操作需要啟動一個新線程來執行。
Android Service只繼承了onCreate(), onStart(),onDestroy()三個方法,當我們第一次啟動Service時,先后調用onCreate(), onStart()這兩個方法,當停止Service時,則執行onDestroy()方法時。如果Service已經啟動了,當我們再次啟動Service時,不會再執行onCreate()方法,而是直接執行onStart()方法。
9. 什么時候使用Service?
答: 比如播放多媒體的時候,用戶啟動了其他Activity,這個時候程序要在后台繼續播放,比如檢測SD卡上文件的變化,再或者在后台記錄你的地理信息位置的改變等等。
10. 請描述一下Intent 和 Intent Filter。
答: Intent在Android中被翻譯為”意圖”,他是三種應用程序基本組件-Activity,Service和broadcast receiver之間相互激活的手段。在調用Intent名稱時使用ComponentName也就是類的全名時為顯示調用。這種方式一般用於應用程序的內部調用,因為你不一定會知道別人寫的類的全名。而Intent Filter是指意圖過濾,不出現在代碼中,而是出現在android Manifest文件中,以<intent-filter>的形式。(有一個例外是broadcast receiver的intent
filter是使用Context.registerReceiver()來動態設定的,其中intent filter也是在代碼中創建的)
一個intent有action,data,category等字段。一個隱式intent為了能夠被某個intent filter接收,必須通過3個測試,一個intent為了被某個組件接收,則必須通過它所有的intent filter中的一個。
11. Intent傳遞數據時,可以傳遞哪些類型數據?
答: intent間傳送數據一般有兩種常用的方法: 1、extra 2、data。
extra可以用Intent.putExtra放入數據。新啟動的Activity可用Intent.getExtras取出Bundle,然后用Bundles.getLong,getInt,getBoolean,getString等函數來取放進去的值。
Data則是傳輸url。url可以是指我們熟悉的http,ftp等網絡地址,也可以指content來指向ContentProvider提供的資源。Intent.setData可以放入數據,Intent.getData可以取出數據。
12. 說說Activity,Intent,Service是什么關系 ?
答: 一個Activity通常是一個單獨的屏幕,每一個Activity都被實現為一個單獨的類,這些類都是從Activity基類中繼承而來的。Activity類會顯示由視圖控件組成的用戶接口,並對視圖控件的事件做出響應。
Intent的調用是用來進行屏幕之間的切換。Intent描述應用想要做什么。Intent數據結構中兩個最重要的部分是動作和動作對應的數據,一個動作對應一個動作數據。
Service是運行在后台的代碼,不能與用戶交互,可以運行在自己的進程里,也可以運行在其他應用程序進程的上下文里。需要一個Activity或者其他Context對象來調用。
Activity跳轉Activity,Activity啟動Service,Service打開Activity都需要Intent表明意圖,以及傳遞參數,Intent是這些組件間信號傳遞的承載着。
13. 請描述一下BroadcastReceiver。
答: Broadcast Receiver用於接收並處理廣播通知(broadcast announcements)。多數的廣播是系統發起的,如地域變換、電量不足、來電短信等。程序也可以播放一個廣播。程序可以有任意數量的broadcast receivers來響應它覺得重要的通知。Broadcast receiver可以通過多種方式通知用戶: 啟動activity、使用NotificationManager、開啟背景燈、振動設備、播放聲音等,最典型的是在狀態欄顯示一個圖標,這樣用戶就可以點它打開看通知內容。通常我們的某個應用或系統本身在某些事件(電池電量不足、來電短信)來臨時會廣播一個Intent出去,我們利用注冊一個broadcast receiver來監聽這些Intent並獲取Intent中的數據。
14. 在manifest和代碼中如何注冊和使用 broadcast receiver 。
答: 在android的manifest中注冊
<receiver android: name =“Receiver1”>
<intent-filter>
<!----和Intent中的action對應--->
<actionandroid: name=“com.forrest.action.mybroadcast”/>
</intent-filter>
</receiver>
在代碼中注冊
1、 IntentFilter filter = new IntentFilter(“com.forrest.action.mybroadcast”);//和廣播中Intent的action對應;
2、 MyBroadcastReceiver br= new MyBroadcastReceiver();
3、 registerReceiver(br, filter);
15. 請介紹下ContentProvider是如何實現數據共享的。
答: 一個程序可以通過實現一個Content provider的抽象接口將自己的數據完全暴露出去,而且Content provider是以類似數據庫中的表的方式將自己的數據暴露。Content provider存儲和檢索數據,通過它可以讓所有的應用程序訪問到,這也是應用程序之間唯一共享數據的方法。
要想使應用程序的數據公開化,可通過2種方法:創建一個數據自己的Content Provider或者將你的數據添加到一個已經存在的Content Provider中,前提是有相同數據類型並且有寫入Content Provider的權限,Android提供了Content Resolverr,外界的程序可以通過Content Resolver接口訪問Content Provider提供的數據。
16. 請介紹下Android的數據存儲方式。
答: Android提供了5中存儲數據的方式,分別是以下幾種
1、使用Shared Preferences存儲數據,用來存儲key-value,pairs格式的數據,它是一個輕量級的鍵值存儲機制,只可以存儲基本數據類型。
2、使用文件存儲數據,通過FileInputStream和FileOutputStream對文件進行操作。在Android中,文件是一個應用程序私有的,一個應用程序無法讀寫其他應用程序的文件。
3、使用SQLite數據庫存儲數據,Android提供的一個標准數據庫,支持SQL語句。
4、使用Content Provider存儲數據,是所有應用程序之間數據存儲和檢索的一個橋梁,它的作用就是使得各個應用程序之間實現數據共享。它是一個特殊的存儲數據的類型,它提供了一套標准的接口用來獲取數據,操作數據。系統也提供了音頻、視頻、圖像和個人信息等幾個常用的Content Provider。如果你想公開自己的私有數據,可以創建自己的Content Provider類,或者當你對這些數據擁有控制寫入的權限時,將這些數據添加到Content Provider中實現共享。外部訪問通過Content Resolver去訪問並操作這些被暴露的數據。
5、使用網絡存儲數據
17. 請介紹下Android中常用的五種布局。
答: 最常用的布局方式為Absolute Layout、Relative Layout、Linear Layout、FrameLayout、TableLayout。其中Linear Layout和Relative Layout是最常用的方式,他們可以通過在xml配置文件或者代碼中進行布局。
1、Frame Layout是最簡單的布局方式,放置的控件都只能羅列到左上角,控件會有重疊,不能進行復雜的布局。
2、Linear Layout可以通過orientation屬性設置線性排列的方向是垂直還是縱向的,每行或每列只有一個元素,可以進行復雜的布局。
3、Absolute Layout可以讓子元素指定准確的x、y坐標值,並顯示在屏幕上。Absolute Layout沒有頁邊框,允許元素之間相互重疊。它是絕對坐標,所以在實際中不提倡使用。
4、Relative Layout允許子元素制定他們相對於其他元素或父元素的位置(通過ID制定)。因此,你可以以右對齊,或上下,或置於屏幕中央的形式來排列兩個元素。元素按順序排列,因此如果第一個元素在屏幕的中央,那么相對於這個元素的其他元素將以屏幕中央的相對位置來排列。這個是相對於Absolute Layout的,采用相對坐標,所以在實際中比較常用。
5、Table Layout將以子元素的位置分配到行或列。一個Table Layout由許多的Table Row組成,每個Table Row都會定義一個row。Table Layout容器不會顯示row、column或者cell的邊線框。每個row擁有0個或多個的cell; 和html中的table差不多。在實際中也經常使用。
18. 談談UI中, Padding和Margin有什么區別?
答: Padding是控件的內容相對控件的邊緣的邊距,而Margin是控件邊緣相對於其他控件的邊距。如下圖所示:
19. android本身的一些限制,比如apk包大小限制,讀取大文件時的時間限。
答:apk包大小限制不好說,有的apk為100M,還是能裝到手機上。一般的apk大小為5~10M左右。讀取大文件的時間應該是在main線程里面,時間限制為5秒左右。
20. ListView如何提高其效率?
答:1、使用分頁加載,不要一次性加載所有數據。
2、復用convertView。在getItemView中,判斷converView是否為空,如果不為空,可復用。
3、異步加載圖片。Item中如果包含有webimage,那么最好異步加載。
4、快速滑動時,不顯示圖片。當快速滑動列表(SCROLL_STATE_FLING),item中的圖片或獲取需要消耗資源的view,可以不顯示出來;而處於其他兩種狀態(SCROLL_STATE_IDLE和SCROLL_STATE_TOUCH_SCROLL),則將那些view顯示出來
21. Android程序與Java程序的區別?
區別 |
Java程序 |
Android程序 |
執行入口點 |
Main |
Android Mainfest.xml配置文件中的intent-filter |
UI |
Frame· |
Activity |
是否基於配置文件 |
否 |
是 |
是否基於組件 |
否 |
是Activity,Service,Broadcast Receiver,Content Provider |
22. 談談對Android NDK的理解。
答: android NDK是一套工具,允許Android應用開發者嵌入從C、C++源代碼編譯來的本地機器代碼到各自的應用軟件包中。
1、 NDK是一系列工具的集合。
NDK提供了一系列的工具,幫助開發者快速開發C(或C++)的動態庫,並能自動將so和java應用一起打包成apk。這些工具對開發者幫助時巨大的。
NDK集成了交叉編輯器,並提供了相應的mk文件隔離CPU、平台、API等差異,開發人員只需要簡單修改mk文件(指出“那些文件需要編譯”、“編譯特性要求”等),就可以創建出so。NDK可以自動將so和Java應用一起打包,極大的減輕了開發人員的打包工作。
2、NDK提供了一份穩定、功能有限的API頭文件聲明。這些API支持的功能非常有限,包含有:C標准庫(libc)、標准數學庫(libm)、壓縮庫(libz)、log庫(liblog)。
23. 談談Android的優點和不足之處。
答: 優點如下所示:
1、android是開源、市場占有率大。
2、android能夠有豐富的硬件選擇。
3、android是一款基於Linux平台的開源操作系統,從而避免了專利壁壘,是一款完全免費的智能手機平台。
4、由於android是google開發的,因此能夠無縫結合Google應用。
缺點如下所示:
1、安全與隱私。手機與互聯網緊密聯系,個人隱私很難得到保護。
24. Android系統中GC什么情況下會出現內存泄露呢?
答: 導致內存泄露主要的原因是,先前申請了內存空間而忘記了釋放。如果程序中存在無用對象的引用,那么這些對象就會駐留內存,消耗內存,因為無法讓垃圾回收器GC驗證這些對象是否不再需要。如果存在對象的引用,這個對象就被定義為“有效的活動”,同時不會被釋放。要確定對象所占內存將被回收,我們就要確認該對象不會再被使用。典型的做法是把對象數據成員設為null或者從集合中移除該對象。當出現以下情況時,會造成內存泄露:
1、 數據庫的cursor沒有關閉。
2、 構造adapter時,沒有使用緩存contentview。
3、 Bitmap對象不使用時,采用recycle()釋放內存。
4、 Activity中的對象的生命周期大於activity。
調試方法: DDMS==>HEAPSIZE==>dataobject==>[TotalSize]
25. Android UI中的View如何刷新。
答: Android中對View的更新方式有很多種,使用時要區分不同的應用場合。要分清的是:多線程和雙緩沖。
1、不使用多線程和雙緩沖
這種情況最簡單,一般只希望View在發生改變時對UI進行重繪。你只需要Activity中顯式調用View對象中的invalidate()方法即可。系統會自動調用View的onDraw()方法。
2、使用多線程和不使用雙緩沖
這種情況下需要開啟新的線程,新開的線程就不好訪問View對象了。強行訪問的話會報錯:android.view.ViewRoot$ CalledFromWrongThreadException: only theoriginal thread that created a view hierarchy can touch its views。
這時候你需要創建一個繼承了android.os.handler的子類,並重寫handleMessage方法。Android.os.Handle是能發送和處理消息的,你需要在Activity中發出更新UI的消息,然后再你的Handler(可以使用匿名內部類)中處理消息(因為匿名內部類可以訪問父類變量,你可以直接調用View對象中的invalidate()方法。也就是說:在新線程中創建並發送一個Message,然后在主線程中捕獲、處理該消息。
3、使用多線程和雙緩沖
Android的SurfaceView是View的子類,她同時也實現了雙緩沖。你可以定義一個她的子類並實現Surfaceholder.Callback接口。由於SurfaceHolder.Callback接口,新線程就不要android.os.Handler幫忙了。SurfaceHolder中lockCanvas()方法可以鎖定畫布,繪制完新的圖像后調用unlockCanvasand Post解鎖。
一、什么是OOM
OOM(out of memory)即內存泄露。一個程序中,已經不需要使用某個對象,但是因為仍然有引用指向它垃圾回收器就無法回收它,當該對象占用的內存無法被回收時,就容易造成內存泄露。
Android的一個應用程序的內存泄露對別的應用程序影響不大,因為為了能夠使得Android應用程序安全且快速的運行,Android的每個應用程序都會使用一個專有的Dalvik虛擬機實例來運行,也就是說每個應用程序都是在屬於自己的進程中運行的。如果程序內存溢出,Android系統只會kill掉該進程,而不會影響其他進程的使用(如果是system_process等系統進程出問題的話,則會引起系統重啟)。
二、出現內存泄露原因
1.資源對象沒關閉造成的內存泄露,try catch finally中將資源回收放到finally語句可以有效避免OOM。資源性對象比如:
1-1,Cursor
1-2,調用registerReceiver后未調用unregisterReceiver()
1-3,未關閉InputStream/OutputStream
1-4,Bitmap使用后未調用recycle()
2.作用域不一樣,導致對象不能被垃圾回收器回收,比如:
2-1,非靜態內部類會隱式地持有外部類的引用,
2-2,Context泄露
概括一下,避免Context相關的內存泄露,記住以下事情:
1、 不要保留對Context-Activity長時間的引用(對Activity的引用的時候,必須確保擁有和Activity一樣的生命周期)
2、嘗試使用Context-Application來替代Context-Activity 3、如果你不想控制內部類的生命周期,應避免在Activity中使用非靜態的內部類,而應該使用靜態的內部類,並在其中創建一個對Activity的弱引用。
這種情況的解決辦法是使用一個靜態的內部類,其中擁有對外部類的WeakReference。
2-3,Thread 引用其他對象也容易出現對象泄露。
2-4,onReceive方法里執行了太多的操作
3.內存壓力過大
3-1,圖片資源加載過多,超過內存使用空間,例如Bitmap 的使用
3-2,重復創建view,listview應該使用convertview和viewholder
三、如何避免內存泄露
1.使用緩存技術,比如LruCache、DiskLruCache、對象重復並且頻繁調用可以考慮對象池
2.對於引用生命周期不一樣的對象,可以用軟引用或弱引用SoftReferner WeakReferner
3.對於資源對象 使用finally 強制關閉
4.內存壓力過大就要統一的管理內存
ANR(Application Not Responding) Android系統中應用無響應
是Android系統中比較常見的問題,當出現ANR時一般情況會彈出一個帶有以下文字的對話框
粗略的來分會有兩種情況導致ANR:
第一類:dispatchTimeout 輸入事件分發超時,一般是由於主線程在5秒之內沒有響應輸入事件。
第二類:BroadcastReceiver沒有在系統設定的時間內完成並返回。
再細分的話ANR可能是由主線程導致也可能是由非主線程導致:
由於主線程導致的情況:
1.耗時網絡訪問
2.當有大量數據讀寫操作時再請求數據讀寫
3.數據庫操作(比如其他大數據量應用訪問數據庫導致數據庫負載過重時)
4.硬件操作(比如Camera)
5.調用thread_join() / Sleep() / Wait() 或者等待locker的時候
6.Service binder數量達到上限
7.在system_server中發生WatchDog ANR
8.Service忙導致超時無響應
由於非主線程導致的情況:
1.非主線程持有lock,導致主線程等待lock超時
2.非主線程終止或者崩潰導致主線程一直等待