50道安卓基礎面試題
常用設計模式及應用場景,用兩種方式實現單例模式,要求執行緒安全? 答: 常用設計模式: 單例模式: Calendar例項的獲取 介面卡模式: Adapter 為ListView GridView等新增資料 工廠模式: Spring IOC 反轉控制 代理模式: Spring AOP 面向切面程式設計 觀察者模式: ContentObserver監聽內容改變 (懶漢式)程式執行過程中需要這個類的物件時再例項化該類的物件 步驟1.定義靜態私有物件 2. 構造方法私有化保證在類的外部無法例項化該類的物件 3. 定義對外開放的靜態方法在呼叫方法是判斷物件是否為空,為空再建立物件返回 public class Singleton {
private static Singleton singleton;
// 構造方法私有化,保證在類的外部無法例項化該類的物件
private Singleton() {
}
public static synchronized Singleton getSingletonInstance() {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
(餓漢式)類載入的時候就例項化該類的物件
public class Singleton {
private static Singleton singleton = new Singleton();
// 構造方法私有化,保證在類的外部無法例項化該類的物件
private Singleton() {
}
public static Singleton getSingletonInstance() {
return singleton;
}
}
12、常用排序演算法,時間複雜度,實現思路
答: 氣泡排序 O(n^2) : 氣泡排序也是最簡單最基本的排序方法之一。氣泡排序的思想很簡單,就是以此比較相鄰的元素大小,將小的前移,大的後移,就像水中的氣泡一樣,最小的元 素經過幾次移動,會最終浮到水面上。
for (int i = 0; i < num.length; i++) {
// 內迴圈控制比較後移位
for (int j = num.length-1; j > i ; j–) {
if (num[j-1]>num[j]) {
temp = num[j-1];
num[j-1] = num[j];
num[j] = temp;
}
}
快速排序O(n log n) : 快速排序採用的思想是分治思想。快速排序演算法的核心演算法是分割槽操作,即如何調整基準的位置以及調整返回基準的最終位置以便分治遞迴。
插入排序 O(n^2) :將新來的元素按順序放入一個已有的有序序列當中。
選擇排序 O(n^2) :第i趟簡單選擇排序是指通過n-i次關鍵字的比較,從n-i+1個記錄中選出關鍵字最小的記錄,並和第i個記錄進行交換。共需進行i-1趟比較,直到所有記錄排序完成為止。
13、android系統架構?
答:1)應用程式層 java語言 應用程式開發
應用程式框架層 java語言 OS定製 framework層開發
系統執行庫層 C C++ 實現 so庫
Linux核心層
Activity生命週期?儲存activity的一些資訊在哪個生命週期方法中?
答:共有七個周期函式:
void onCreate(Bundle savedInstanceState) 第一次建立時呼叫
void onStart() 被使用者可見時呼叫
void onRestart() 當Activity處於stop狀態又被重新啟動時呼叫
void onResume() 當獲得焦點即可與使用者互動時呼叫
void onPause() 當失去焦點時呼叫
void onStop() 當不可見時呼叫
void onDestroy() 當銷燬時呼叫
Activity的 onSaveInstanceState() 和 onRestoreInstanceState()
答: Activity的 onSaveInstanceState() 和 onRestoreInstanceState()並不是生命週期方法,它們不同於 onCreate()、onPause()等生命週期方法,它們並不一定會被觸發。當應用遇到意外情況(如:記憶體不足、使用者直接按Home鍵)由系統銷燬一個Activity時,onSaveInstanceState() 會被呼叫。但是當用戶主動去銷燬一個Activity時,例如在應用中按返回鍵,onSaveInstanceState()就不會被呼叫。因為在這種情況下,使用者的行為決定了不需要儲存Activity的狀態。通常onSaveInstanceState()只適合用於儲存一些臨時性的狀態,而onPause()適合用於資料的持久化儲存。
另外,當螢幕的方向發生了改變, Activity會被摧毀並且被重新建立,如果你想在Activity被摧毀前快取一些資料,並且在Activity被重新建立後恢復快取的資料。可以重寫Activity的 onSaveInstanceState() 和 onRestoreInstanceState()方法。
Android的四大元件是什麼?它們的作用是什麼?
答:Android有四大元件:Activity、Service、Broadcast Receiver、Content Provider。
Activity :應用程式中,一個Activity通常就是一個單獨的螢幕,它上面可以顯示一些控制元件也可以監聽並處理使用者的事件做出響應。Activity之間通過Intent進行通訊。
Service 服務:一個Service 是一段長生命週期的,沒有使用者介面的程式,可以用來開發如監控類程式。
BroadcastReceive廣播接收器:你的應用可以使用它對外部事件進行過濾只對感興趣的外部事件(如當電話呼入時,或者資料網路可用時)進行接收並做出響應。廣播接收器沒有使用者介面。然而,它們可以啟動一個activity或serice 來響應它們收到的資訊。
Content Provider內容提供者 :主要用於多個應用間資料共享。這些資料可以儲存在檔案系統中或SQLite資料庫。
廣播如何呼叫,有什麼方式,各自的區別?
答:程式中傳送廣播通過sendBroadcastReceiver()實現
接收廣播通過定義一個類繼承BroadcastReceiver並重寫onReceive()方法實現
註冊廣播有兩種方式:
第一種靜態方式:在清單檔案中通過標籤宣告
第二種程式碼動態方式:
IntentFilter filter = new IntentFilter(“android.provider.Telephony.SMS_RECEIVED”);
IncomingSMSReceiver receiver = new IncomgSMSReceiver();
registerReceiver(receiver.filter);
1)第一種不是常駐型廣播,也就是說廣播跟隨activity的生命週期。注意: 在activity結束前,移除廣播接收器。
2)第二種是常駐型,也就是說當應用程式關閉後,如果有資訊廣播來,程式也會被系統呼叫自動執行。
Android中asset資料夾和raw資料夾區別?
答:res/raw和assets的相同點:
兩者目錄下的檔案在打包後會原封不動的儲存在apk包中,不會被編譯成二進位制。
res/raw和assets的不同點:
1)res/raw中的檔案會被對映到R.java檔案中,訪問的時候直接使用資源ID即 R.raw.filename;assets資料夾下的檔案不會被對映到R.java中,訪問的時候需要AssetManager類。
2)res/raw不可以有目錄結構,而assets則可以有目錄結構,也就是assets目錄下可以再建立資料夾
3)讀取檔案資源舉例:
讀取res/raw下的檔案資源,通過以下方式獲取輸入流來進行寫操作
InputStream is = getResources().openRawResource(R.raw.filename);
讀取assets下的檔案資源,通過以下方式獲取輸入流來進行寫操作
AssetManager am = null;
am = getAssets();
InputStream is = am.open(“filename”);
Android中的五種儲存方式及其應用場景
答:1)SharedPreferences
儲存路徑:(data/data/packagename/shares_prefs), 輕量級儲存,以鍵值對的形式儲存在xml中,一般用來儲存應用中的設定屬性
2)檔案儲存 SD卡儲存多媒體檔案, 檔案快取
3) Sqlite資料庫 儲存路徑:(data/data/packagename/databases), 一種嵌入式資料庫,支援sql語言,儲存大量結構性資料
4)ContentProvider 程序(應用程式)間資料共享,資料來源可以是sqlite,也可以是xml,相關類: ContentResolver(內容解析器), ContentObserver(資料 觀察者)
5) 網路儲存 天氣資料的xml,json格式等等,通過HttpUrlConnection,HttpClient,或者SOAP協議獲取資料
什麼是ANR 如何避免它?(Android執行緒間的通訊方式? )
答:ANR:Application Not Responding(應用程式無響應).當出現下列情況時,Android就會顯示ANR對話方塊了: 對輸入事件(如按鍵、觸控式螢幕事件)的響應超過5秒 意向接受器(intentReceiver)超過10秒鐘仍未執行完畢Android應用程式完全執行在一個獨立的執行緒中(例如main)。這就意味著,任何在主執行緒中執行的,需要消耗大量時間的操作都會引發ANR。
解決方案有兩種:
- AsyncTask非同步任務中,doInBackground()和onPostExecute(Result)兩個方法非常重要
doInBackground() 這個方法執行在後臺執行緒中,主要負責執行那些很耗時的操作,如移動護理系統中的網路連線、解析XML等操作。該方法必須過載。
onPostExecute(Result) 這個方法也運行於UI執行緒,在doInBackground(Params…)方法執行後呼叫,該方法用於處理後臺任務執行後返回的結果。 - 子thread + handler
Handler的執行機制(執行原理)(Handler,Looper,MessageQueue,Message之間的關係)
一個Handler允許你傳送和處理Message和Runable物件,每個執行緒都有自己的Looper,每個Looper中封裝著MessageQueue。Looper負責不斷的從自己的訊息佇列裡取出隊頭的任務或訊息執行。每個handler也和執行緒關聯,Handler負責把Message和Runable物件傳遞給MessageQueue(用到post ,sendMessage等方法),而且在這些物件離開MessageQueue時,Handler負責執行他們(用到handleMessage方法)。
其中Message類就是定義了一個資訊,這個資訊中包含一個描述符和任意的資料物件,這個資訊被用來傳遞給Handler.Message物件提供額外的兩個int域和一個Object域。
listview優化策略?
答:1)、對convetView進行判空,是當convertView不為空的時候直接重新使用convertView
從而減少了很多不必要的View的建立
2)定義一個ViewHolder,將convetView的tag設定為ViewHolder,不為空時重新使用即可
3)、當ListView載入資料量較大時可以採用分頁載入和圖片非同步載入
ListView分頁載入實現思路?
實現OnScrollListener 介面重寫onScrollStateChanged 和onScroll方法,使用onscroll方法實現”滑動“後處理檢查是否還有新的記錄,如果有,呼叫 addFooterView,新增記錄到adapter, adapter呼叫 notifyDataSetChanged 更新資料;如果沒有記錄了,把自定義的mFooterView去掉。使用onScrollStateChanged可以檢測是否滾到最後一行且停止滾動然後執行載入
ListView圖片非同步載入實現思路?
1.先從記憶體快取中獲取圖片顯示(記憶體緩衝)
2.獲取不到的話從SD卡里獲取(SD卡緩衝,,從SD卡獲取圖片是放在子執行緒裡執行的,否則快速滑屏的話會不夠流暢)
3.都獲取不到的話從網路下載圖片並儲存到SD卡同時加入記憶體並顯示(視情況看是否要顯示)
Intent的原理,作用,可以傳遞哪些型別的引數?
答:intent是連線Activity, Service, BroadcastReceiver, ContentProvider四大元件的信使,,可以傳遞八種基本資料型別以及string, Bundle型別,以及實現了Serializable或者Parcelable的型別。
Intent可以劃分成顯式意圖和隱式意圖。
顯式意圖:呼叫Intent.setComponent()或Intent.setClass()方法明確指定了元件名的Intent為顯式意圖,顯式意圖明確指定了Intent應該傳遞給哪個元件。
隱式意圖:沒有明確指定元件名的Intent為隱式意圖。 Android系統會根據隱式意圖中設定的動作(action)、類別(category)、資料(URI和資料型別)找到最合適的元件來處理這個意圖。
如何實現螢幕解析度的自適應?
答: 最好可以通過權重(layout_weight)的方式來分配每個元件的大小,也可以通過具體的畫素(dip)來確定大小。
儘量使用Relativelayout 。
已知應用支援平臺裝置的解析度,可以提供多個layout_320480 …
drawable-hdpi,drawable-mdpi,drawable-ldpi分別代表解析度為480800,360480,240360, 放置圖片大小相差1.5倍
最後還需要在AndroidManifest.xml裡新增下面一段,沒有這一段自適應就不能實現:
在標籤和 標籤之間新增上面那段程式碼。即可。
備註:三者的解析度不一樣,就像你把電腦的解析度調低,圖片會變大一樣,反之解析度高,圖片縮小
還可以通過.9.png實現圖片的自適應
簡述Android中的IPC機制
IPC(Inter-Process Communication,程序間通訊),aidl是 Android Interface definition language的縮寫,它是一種android內部程序通訊介面的描述語言,通過它我們可以定義程序間的通訊介面.編譯器可以通過副檔名為aidl的檔案生成一段程式碼,通過預先定義的介面達到兩個程序內部通訊程序的目的.
BroadcastReceiver也可以實現程序間通訊
ContentProvider 提供程序間資料共享
Android程式入口如何判斷?
action節點中的android.intent.action.MAIN表明它所在的Activity是整個應用程式的入口點
android哪幾種方式訪問網路?
HttpURLConnection
HttpClient方式(HttpGet和HttpPost類)
說說HttpClient的通訊過程
1.生成請求物件(HttpGet get,HttpPost post)
2.生成客戶端物件 HttpClient client
3.執行請求接收相應 HttpResponse response = client.execute(post)
HttpEntity entity = response.getEntity()
4.得到資料流
InputStream inputStream = entity.getContent();
5.最後關閉過期連線
移動互聯資料互動格式有哪些及其區別?(Json與xml的區別?)
移動互聯資料互動格式有XML和JSON
1.JSON和XML的資料可讀性基本相同
2.JSON和XML同樣擁有豐富的解析手段
3.JSON相對於XML來講,資料的體積小
4.JSON與JavaScript的互動更加方便
5.JSON對資料的描述性比XML較差
6.JSON的速度要遠遠快於XML
XML解析有哪幾種?各自優缺點,官方推薦使用哪種?
基本的解析方式有三種: DOM,SAX,Pull
1.dom解析解析器讀入整個文件,然後構建一個駐留記憶體的樹結構,然後程式碼就可以使用 DOM 介面來操作這個樹結構的優點是對文件增刪改查比較方便,缺點佔用記憶體比較大。
2.sax解析基於事件驅動型,優點佔用記憶體少,解析速度快,缺點是隻適合做文件的讀取,不適合做文件的增刪改查。
3.pull解析同樣基於事件驅動型,android 官方API提供,可隨時終止
百度地圖核心類,及實現的功能?
BMapManager:地圖引擎管理類,負責初始化,開啟地圖API,終止百度地圖API等工作
MKSearch:搜尋服務.用於位置檢索、周邊檢索、範圍檢索、公交檢索、駕乘檢索、步行檢索
MKSearchListener搜尋結果通知介面。該介面返回poi搜尋,公交搜尋,駕乘路線,步行路線結果
MapView:顯示地圖的View
MyLocationOverlay:一個負責顯示使用者當前位置的Overlay。
Overlay:Overlay是一個基類,它表示可以顯示在地圖上方的覆蓋物。
GC記憶體洩露在什麼情況下回出現?怎麼解決?
查詢資料庫沒有關閉遊標
構造Adapter時,沒有使用快取的 convertView
Bitmap物件不在使用時呼叫recycle()釋放記憶體
不用的物件沒有及時釋放物件的引用
android記憶體的優化
答:android記憶體洩露容易導致記憶體溢位,又稱為OOM。
Android記憶體優化策略:
1)在迴圈內儘量不要使用區域性變數
2)不用的物件即時釋放,即指向NULL
3)資料庫的cursor即時關閉。
4)構造adapter時使用快取contentview
5)呼叫registerReceiver()後在對應的生命週期方法中呼叫unregisterReceiver()
6)即時關閉InputStream/OutputStream。
7)android系統給圖片分配的記憶體只有8M, 圖片儘量使用軟引用, 較大圖片可通過BitmapFactory縮放後再使用,並及時recycle
8)儘量避免static成員變數引用資源耗費過多的例項。
載入大圖片的時候如何防止記憶體溢位
答: android系統給圖片分配的記憶體只有8M,當載入大量圖片時往往會出現OOM。
Android載入大量圖片記憶體溢位解決方案:
1)儘量不要使用setImageBitmap或setImageResource或BitmapFactory.decodeResource來設定一張大圖,因為這些函式在完成decode後,最終都是通過java層的createBitmap來完成的,需要消耗更多記憶體,可以通過BitmapFactory.decodeStream方法,創建出一個bitmap,再將其設為ImageView的 source
2)使用BitmapFactory.Options對圖片進行壓縮
InputStream is = this.getResources().openRawResource(R.drawable.pic1);
BitmapFactory.Options options=new BitmapFactory.Options();
options.inJustDecodeBounds = false;
options.inSampleSize = 10; //width,hight設為原來的十分一
Bitmap btp =BitmapFactory.decodeStream(is,null,options);
3)運用Java軟引用,進行圖片快取,將需要經常載入的圖片放進快取裡,避免反覆載入
及時銷燬不再使用的Bitmap物件
if(!bmp.isRecycle() ){
bmp.recycle() //回收圖片所佔的記憶體
system.gc() //提醒系統及時回收
}
Android快取機制
答: 客戶端快取機制是android應用開發中非常重要的一項工作,使用快取機制不僅僅可以為使用者節省3G流量,同時在使用者體驗方面也是非常好的選擇,比如有些新聞客戶端支援離線模式,也是通過快取機制實現的.快取機制分為兩部分,一部分是文字快取,另一部分是多媒體檔案快取.
文字快取有兩種實現:
1)可以將與伺服器互動得到的json資料或者xml資料存入sd卡中,並在資料庫新增該資料的記錄.新增資料庫記錄時,提供兩個關鍵欄位,一個是請求的URL,另一個則是本地儲存後的檔案地址,每次載入資料之前都會根據URL在資料庫中檢索
2)將JSON資料解析後裝入List
- 每一個模組在每次客戶端自動或者使用者手動更新的時候刪除相應模組的快取檔案,並重新下載新的快取檔案.
- 在設定介面中提供刪除快取的功能,點選後刪除本機所有快取.
如何實現訊息推送,有哪些方式,各自優缺點,最常使用哪種?
答:實現訊息推送的方式有五種,分別是輪詢,SMS,C2DM,MQTT,XMPP最常使用的是XMPP, 我們做專案時採用的是XMPP協議
1.XMPP協議,它是一種基於XML的傳遞協議,具有很強的靈活性和可擴充套件性。它的特點是將複雜性從客戶端轉移到了伺服器端。GTalk、QQ、IM等都用這個協議。
2.輪詢:客戶端定時去服務端取或者保持一個長Socket,從本質講這個不叫推送, 而是去服務端拽資料。但是實現簡單,主要缺點:耗電,浪費使用者流量等
3.Google的C2DM,具體不細說,缺點,伺服器在國外,不是很穩定。
4.通過簡訊方式, 但是很難找到免費簡訊平臺 - MQTT協議, IBM提供的一種推送服務,不太靈活
MVC在Android中的應用
答: Android中介面部分也採用了當前比較流行的MVC框架,在Android中:
1) 檢視層(View):一般採用XML檔案進行介面的描述,使用的時候可以非常方便的引入。也可以使用JavaScript+HTML等的方式作為View層,通過WebView元件載入,同時可以實現Java和JavaScript之間的通訊。
2) 控制層(Controller):這句話也就暗含了不要在Acitivity中寫程式碼,要通過Activity交割Model業務邏輯層處理,這樣做的另外一個原因是Android中的Acitivity的響應時間是5s,如果耗時的操作放在這裡,Android的控制層的重任通常落在了眾多的Acitvity的肩上,程式就很容易被回收掉。
- 模型層(Model):對資料庫的操作、對網路等的操作都應該在Model裡面處理,當然對業務計算等操作也是必須放在的該層的。
在Android SDK中的資料繫結,也都是採用了與MVC框架類似的方法來顯示資料。在控制層上將資料按照檢視模型的要求(也就是Android SDK中的Adapter)封裝就可以直接在檢視模型上顯示了,從而實現了資料繫結。比如顯示Cursor中所有資料的ListActivity,其檢視層就是一個ListView,將資料封裝為ListAdapter,並傳遞給ListView,資料就在ListView中顯示。
Android自定義元件實現思路
答: Android自定義元件有三種實現思路:
繼承某個現有元件,在其基礎上新增額外功能,如繼承Gallery實現CoverFlow效果
繼承某個Layout,實現複合元件自定義,如TextView和EditText組合實現登入註冊元件
繼承View,實現onDraw()方法,實現自己繪製元件,如翻頁效果元件
版本更新的實現思路
答:在伺服器相應URL上有版本檔案, 客戶端同時儲存該應用當前版本號 (SharedPreferences/Sqlite), 每次開啟應用,去檢測伺服器版本號與本地版本號是否一致,如果不一 致,則自定義對話方塊提示是否下載更新
42、播放視訊有哪些實現方式?
答:1.使用系統自帶的播放器來播放,指定Action為ACTION_VIEW,Data為Uri,Type為其MIME型別。
//呼叫系統自帶的播放器
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri, "video/mp4");
startActivity(intent);
- 使用VideoView元件來播放, 可以結合MediaController來實現播控, 只是不能隨意更改視訊的大小及位置。
- 使用MediaPlayer和SurfaceView來實現,這種方式很靈活,可以自定義視訊播放的大小和位置。
43、NDK開發流程?(JNI執行原理)
答: NDK應用的開發流程(在應用中定義本地介面(native), 編譯成.h標頭檔案,交由C程式設計師實現,將.c實現通過NDK編譯成.so動態連結庫,匯入專案中libs/armeabi,程式碼中呼叫該本地介面)
應用場景: 音訊,視訊解碼,拍攝車牌號,識別車牌號
44、如何實現一鍵退出?
答:定義一個類繼承Application,定義一個集合存放所有的activity,
定義一個新增的方法,再寫一個退出的方法,使用for迴圈全部呼叫finish方法,然
後在每個Activity的onCreate方法中呼叫自定義類裡的新增方法,然後在需要使用一
鍵退出的地方呼叫類中的退出方法即可。
45、AndroidManifest.xml清單檔案標籤中屬性android:excludeFromRecents=“true” android:screenOrientation=“portrait” android:configChanges="orientation|locale"的含義
答: android:excludeFromRecents表示是否可被顯示在最近開啟的activity列表裡,true表示否,false表示是
android:screenOrientation表示activity顯示的模式, 一般用來設定activity橫屏顯示(horizontal)或豎屏顯示(portrait)
android:configChanges=[oneormoreof:“mcc”“mnc”“locale”“touchscreen”“keyboard”“keyboardHidden”“navigation”“orientation”“fontScale”]是當所指定屬性(Configuration Changes)發生改變時,通知程式呼叫 onConfigurationChanged()函式,比如orientation螢幕方向發生改變,locale語言環境發生改變時
46、如何將一個Activity設定成視窗的樣式
答:在清單檔案AndroidManifest.xml中相應的標籤內設定屬性android:theme=”@android:style/Theme.Dialog”
47、談談UI中, Padding和Margin有什麼區別,gravity與layout_gravity的區別
答:Padding 用來指定元件內的內容距離元件邊界的距離;
Margin用來指定控制元件與控制元件之間的距離
Gravity用來指定元件內的內容相對於元件本身的位置
Layout_gravity用來指定元件相對於其父元件的位置
48、哪個元件可以實現手風琴效果,用來實現設定介面的類,實現抽屜效果, 懸浮視窗?
答:實現手風琴效果(ExpandableListView)
設定介面的類(preferenceActivity)儲存到sharedpreference中
抽屜效果(slidingDrawer)元件
懸浮視窗: PopWindow,可以實現類似Dialog和選單的效果
49、Android SDK 3.0(HoneyComb)及4.0(Ice Cream)新特性
答:新版SDK釋出的同時也釋出了一個擴充套件包android-support-v4,把部分特性單獨的抽出來,使低版本的SDK也可以使用這些特性,主要支援以下特性:
Fragment: 3.0引入,碎片管理,可以區域性重新整理UI,它設計的功能和Activity一樣強大,包括生命週期、導航等,Fragment的每次導航都可以記錄下來用於返回。
ViewPager: 提供了多介面切換的新效果
GridLayout: 4.0引入, 網格佈局, android第六大布局