Android是一種基於Linux的自由及開放原始碼的作業系統,主要使用於移動裝置,如智慧手機和平板電腦,由Google公司和開放手機聯盟領導及開發。這裡會不斷收集和更新Android基礎相關的面試題,目前已收集100題。
1.Android系統的架構
- Android系統架構之應用程式
Android會同一系列核心應用程式包一起釋出,該應用程式包包括email客戶端,SMS短訊息程式,日曆,地圖,瀏覽器,聯絡人管理程式等。所有的應用程式都是使用JAVA語言編寫的。 - Android系統架構之應用程式框架
開發人員可以完全訪問核心應用程式所使用的API框架(android.jar)。該應用程式的架構設計簡化了元件的重用;任何一個應用程式都可以釋出它的功能塊並且任何其它的應用程式都可以使用其所釋出的功能塊。 - Android系統架構之系統執行庫
Android 包含一些C/C++庫,這些庫能被Android系統中不同的元件使用。它們通過 Android 應用程式框架為開發者提供服務。 - Android系統架構之Linux 核心
Android 的核心繫統服務依賴於 Linux 2.6 核心,如安全性,記憶體管理,程式管理, 網路協議棧和驅動模型。 Linux 核心也同時作為硬體和軟體棧之間的抽象層。
2.activity的生命週期
Activity生命週期方法主要有onCreate()、onStart()、onResume()、onPause()、onStop()、onDestroy()和onRestart()等7個方法。
- 啟動一個A Activity,分別執行onCreate()、onStart()、onResume()方法。
- 從A Activity開啟B Activity分別執行A onPause()、B onCreate()、B onStart()、B onResume()、A onStop()方法。
- 關閉B Activity,分別執行B onPause()、A onRestart()、A onStart()、A onResume()、B onStop()、B onDestroy()方法。
- 橫豎屏切換A Activity,清單檔案中不設定android:configChanges屬性時,先銷燬onPause()、onStop()、onDestroy()再重新建立onCreate()、onStart()、onResume()方法,設定orientation|screenSize(一定要同時出現)屬性值時,不走生命週期方法,只會執行onConfigurationChanged()方法。
- Activity之間的切換可以看出onPause()、onStop()這兩個方法比較特殊,切換的時候onPause()方法不要加入太多耗時操作否則會影響體驗。
3.Fragment的生命週期
Fragment的生命週期
Fragment與Activity生命週期對比
Fragment的生命週期方法主要有onAttach()、onCreate()、onCreateView()、onActivityCreated()、onstart()、onResume()、onPause()、onStop()、onDestroyView()、onDestroy()、onDetach()等11個方法。
- 切換到該Fragment,分別執行onAttach()、onCreate()、onCreateView()、onActivityCreated()、onstart()、onResume()方法。
- 鎖屏,分別執行onPause()、onStop()方法。
- 亮屏,分別執行onstart()、onResume()方法。
- 覆蓋,切換到其他Fragment,分別執行onPause()、onStop()、onDestroyView()方法。
- 從其他Fragment回到之前Fragment,分別執行onCreateView()、onActivityCreated()、onstart()、onResume()方法。
4.Service生命週期
在Service的生命週期裡,常用的有:
4個手動呼叫的方法
startService() 啟動服務
stopService() 關閉服務
bindService() 繫結服務
unbindService() 解綁服務複製程式碼
5個內部自動呼叫的方法
onCreat() 建立服務
onStartCommand() 開始服務
onDestroy() 銷燬服務
onBind() 繫結服務
onUnbind() 解綁服務複製程式碼
- 手動呼叫startService()啟動服務,自動呼叫內部方法:onCreate()、onStartCommand(),如果一個Service被startService()多次啟動,那麼onCreate()也只會呼叫一次。
- 手動呼叫stopService()關閉服務,自動呼叫內部方法:onDestory(),如果一個Service被啟動且被繫結,如果在沒有解綁的前提下使用stopService()關閉服務是無法停止服務的。
- 手動呼叫bindService()後,自動呼叫內部方法:onCreate()、onBind()。
- 手動呼叫unbindService()後,自動呼叫內部方法:onUnbind()、onDestory()。
- startService()和stopService()只能開啟和關閉Service,無法操作Service,呼叫者退出後Service仍然存在;bindService()和unbindService()可以操作Service,呼叫者退出後,Service隨著呼叫者銷燬。
5.Android中動畫
Android中動畫分別幀動畫、補間動畫和屬性動畫(Android 3.0以後的)
幀動畫
幀動畫是最容易實現的一種動畫,這種動畫更多的依賴於完善的UI資源,他的原理就是將一張張單獨的圖片連貫的進行播放,從而在視覺上產生一種動畫的效果;有點類似於某些軟體製作gif動畫的方式。在有些程式碼中,我們還會看到android:oneshot="false" ,這個oneshot 的含義就是動畫執行一次(true)還是迴圈執行多次。
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="@drawable/a_0"
android:duration="100" />
<item
android:drawable="@drawable/a_1"
android:duration="100" />
<item
android:drawable="@drawable/a_2"
android:duration="100" />
</animation-list>複製程式碼
補間動畫
補間動畫又可以分為四種形式,分別是 alpha(淡入淡出),translate(位移),scale(縮放大小),rotate(旋轉)。
補間動畫的實現,一般會採用xml 檔案的形式;程式碼會更容易書寫和閱讀,同時也更容易複用。Interpolator 主要作用是可以控制動畫的變化速率 ,就是動畫進行的快慢節奏。pivot 決定了當前動畫執行的參考位置
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@[package:]anim/interpolator_resource"
android:shareInterpolator=["true" | "false"] >
<alpha
android:fromAlpha="float"
android:toAlpha="float" />
<scale
android:fromXScale="float"
android:toXScale="float"
android:fromYScale="float"
android:toYScale="float"
android:pivotX="float"
android:pivotY="float" />
<translate
android:fromXDelta="float"
android:toXDelta="float"
android:fromYDelta="float"
android:toYDelta="float" />
<rotate
android:fromDegrees="float"
android:toDegrees="float"
android:pivotX="float"
android:pivotY="float" />
<set>
...
</set>
</set>複製程式碼
屬性動畫
屬性動畫,顧名思義它是對於物件屬性的動畫。因此,所有補間動畫的內容,都可以通過屬性動畫實現。屬性動畫的執行機制是通過不斷地對值進行操作來實現的,而初始值和結束值之間的動畫過渡就是由ValueAnimator這個類來負責計算的。它的內部使用一種時間迴圈的機制來計算值與值之間的動畫過渡,我們只需要將初始值和結束值提供給ValueAnimator,並且告訴它動畫所需執行的時長,那麼ValueAnimator就會自動幫我們完成從初始值平滑地過渡到結束值這樣的效果。除此之外,ValueAnimator還負責管理動畫的播放次數、播放模式、以及對動畫設定監聽器等。
6.Android中4大元件
- Activity:Activity是Android程式與使用者互動的視窗,是Android構造塊中最基本的一種,它需要為保持各介面的狀態,做很多持久化的事情,妥善管理生命週期以及一些跳轉邏輯。
- BroadCast Receiver:接受一種或者多種Intent作觸發事件,接受相關訊息,做一些簡單處理,轉換成一條Notification,統一了Android的事件廣播模型。
- Content Provider:是Android提供的第三方應用資料的訪問方案,可以派生Content Provider類,對外提供資料,可以像資料庫一樣進行選擇排序,遮蔽內部資料的儲存細節,向外提供統一的介面模型,大大簡化上層應用,對資料的整合提 供了更方便的途徑。
- service:後臺服務於Activity,封裝有一個完整的功能邏輯實現,接受上層指令,完成相關的事務,定義好需要接受的Intent提供同步和非同步的介面。
7.Android中常用佈局
常用的佈局:
FrameLayout(幀佈局):所有東西依次都放在左上角,會重疊
LinearLayout(線性佈局):按照水平和垂直進行資料展示
RelativeLayout(相對佈局):以某一個元素為參照物,來定位的佈局方式複製程式碼
不常用的佈局:
TableLayout(表格佈局): 每一個TableLayout裡面有表格行TableRow,TableRow裡面可以具體定義每一個元素(Android TV上使用)
AbsoluteLayout(絕對佈局):用X,Y座標來指定元素的位置,元素多就不適用。(機頂盒上使用)複製程式碼
新增佈局:
PercentRelativeLayout(百分比相對佈局)可以通過百分比控制控制元件的大小。
PercentFrameLayout(百分比幀佈局)可以通過百分比控制控制元件的大小。複製程式碼
8.訊息推送的方式
- 方案1、使用極光和友盟推送。
方案2、使用XMPP協議(Openfire + Spark + Smack)
- 簡介:基於XML協議的通訊協議,前身是Jabber,目前已由IETF國際標準化組織完成了標準化工作。
- 優點:協議成熟、強大、可擴充套件性強、目前主要應用於許多聊天系統中,且已有開源的Java版的開發例項androidpn。
缺點:協議較複雜、冗餘(基於XML)、費流量、費電,部署硬體成本高。
方案3、使用MQTT協議(更多資訊見:mqtt.org/)
- 簡介:輕量級的、基於代理的“釋出/訂閱”模式的訊息傳輸協議。
- 優點:協議簡潔、小巧、可擴充套件性強、省流量、省電,目前已經應用到企業領域(參考:mqtt.org/software),且…
- 缺點:不夠成熟、實現較複雜、服務端元件rsmb不開源,部署硬體成本較高。
- 方案4、使用HTTP輪循方式
- 簡介:定時向HTTP服務端介面(Web Service API)獲取最新訊息。
- 優點:實現簡單、可控性強,部署硬體成本低。
- 缺點:實時性差。
9.android的資料儲存
- 使用SharedPreferences儲存資料;它是Android提供的用來儲存一些簡單配置資訊的一種機制,採用了XML格式將資料儲存到裝置中。只能在同一個包內使用,不能在不同的包之間使用。
- 檔案儲存資料;檔案儲存方式是一種較常用的方法,在Android中讀取/寫入檔案的方法,與Java中實現I/O的程式是完全一樣的,提供了openFileInput()和openFileOutput()方法來讀取裝置上的檔案。
- SQLite資料庫儲存資料;SQLite是Android所帶的一個標準的資料庫,它支援SQL語句,它是一個輕量級的嵌入式資料庫。
- 使用ContentProvider儲存資料;主要用於應用程式之間進行資料交換,從而能夠讓其他的應用儲存或讀取此Content Provider的各種資料型別。
- 網路儲存資料;通過網路上提供給我們的儲存空間來上傳(儲存)和下載(獲取)我們儲存在網路空間中的資料資訊。
10.Activity啟動模式
介紹 Android 啟動模式之前,先介紹兩個概念task和taskAffinity
- task:翻譯過來就是“任務”,是一組相互有關聯的 activity 集合,可以理解為 Activity 是在 task 裡面活動的。 task 存在於一個稱為 back stack 的資料結構中,也就是說, task 是以棧的形式去管理 activity 的,所以也叫可以稱為“任務棧”。
- taskAffinity:官方文件解釋是:"The task that the activity has an affinity for.",可以翻譯為 activity 相關或者親和的任務,這個引數標識了一個 Activity 所需要的任務棧的名字。預設情況下,所有Activity所需的任務棧的名字為應用的包名。 taskAffinity 屬性主要和 singleTask 啟動模式或者 allowTaskReparenting 屬性配對使用。
4種啟動模式
- standard:標準模式,也是系統預設的啟動模式。假如 activity A 啟動了 activity B , activity B 則會執行在 activity A 所在的任務棧中。而且每次啟動一個 Activity ,都會重新建立新的例項,不管這個例項在任務中是否已經存在。非 Activity 型別的 context (如 ApplicationContext )啟動 standard 模式的 Activity 時會報錯。非 Activity 型別的 context 並沒有所謂的任務棧,由於上面第 1 點的原因所以系統會報錯。此解決辦法就是為待啟動 Activity 指定 FLAG_ACTIVITY_NEW_TASK 標記位,這樣啟動的時候系統就會為它建立一個新的任務棧。這個時候待啟動 Activity 其實是以 singleTask 模式啟動的。
- singleTop:棧頂複用模式。假如 activity A 啟動了 activity B ,就會判斷 A 所在的任務棧棧頂是否是 B 的例項。如果是,則不建立新的 activity B 例項而是直接引用這個棧頂例項,同時 onNewIntent 方法會被回撥,通過該方法的引數可以取得當前請求的資訊;如果不是,則建立新的 activity B 例項。
- singleTask:棧內複用模式。在第一次啟動這個 Activity 時,系統便會建立一個新的任務,並且初始化 Activity 的例項,放在新任務的底部。不過需要滿足一定條件的。那就是需要設定 taskAffinity 屬性。前面也說過了, taskAffinity 屬性是和 singleTask 模式搭配使用的。
- singleInstance:單例項模式。這個是 singleTask 模式的加強版,它除了具有 singleTask 模式的所有特性外,它還有一點獨特的特性,那就是此模式的 Activity 只能單獨地位於一個任務棧,不與其他 Activity 共存於同一個任務棧。
11.廣播註冊
首先寫一個類要繼承BroadCastReceiver
第一種:在清單檔案中宣告,新增
<receive android:name=".BroadCastReceiverDemo">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED">
</intent-filter>
</receiver>複製程式碼
第二種:使用程式碼進行註冊如:
IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
BroadCastReceiverDemo receiver = new BroadCastReceiver();
registerReceiver(receiver, filter);複製程式碼
兩種註冊型別的區別是:
a.第一種是常駐型廣播,也就是說當應用程式關閉後,如果有資訊廣播來,程式也會被系統呼叫自動執行。
b.第二種不是常駐廣播,也就是說廣播跟隨程式的生命週期。
12.Android中的ANR
ANR的全稱application not responding 應用程式未響應。
在android中Activity的最長執行時間是5秒。
BroadcastReceiver的最長執行時間則是10秒。
Service的最長執行時間則是20秒。複製程式碼
超出執行時間就會產生ANR。注意:ANR是系統丟擲的異常,程式是捕捉不了這個異常的。
解決方法:
- 執行在主執行緒裡的任何方法都儘可能少做事情。特別是,Activity應該在它的關鍵生命週期方法 (如onCreate()和onResume())裡儘可能少的去做建立操作。(可以採用重新開啟子執行緒的方式,然後使用Handler+Message 的方式做一些操作,比如更新主執行緒中的ui等)
- 應用程式應該避免在BroadcastReceiver裡做耗時的操作或計算。但不再是在子執行緒裡做這些任務(因為 BroadcastReceiver的生命週期短),替代的是,如果響應Intent廣播需要執行一個耗時的動作的話,應用程式應該啟動一個 Service。
13.ListView優化
- convertView重用,利用好 convertView 來重用 View,切忌每次 getView() 都新建。ListView 的核心原理就是重用 View,如果重用 view 不改變寬高,重用View可以減少重新分配快取造成的記憶體頻繁分配/回收;
- ViewHolder優化,使用ViewHolder的原因是findViewById方法耗時較大,如果控制元件個數過多,會嚴重影響效能,而使用ViewHolder主要是為了可以省去這個時間。通過setTag,getTag直接獲取View。
- 減少Item View的佈局層級,這是所有layout都必須遵循的,佈局層級過深會直接導致View的測量與繪製浪費大量的時間。
- adapter中的getView方法儘量少使用邏輯
- 圖片載入採用三級快取,避免每次都要重新載入。
- 嘗試開啟硬體加速來使ListView的滑動更加流暢。
- 使用 RecycleView 代替。
14.Android數字簽名
- 所有的應用程式都必須有數字證照,Android系統不會安裝一個沒有數字證照的應用程式
- Android程式包使用的數字證照可以是自簽名的,不需要一個權威的數字證照機構簽名認證
- 如果要正式釋出一個Android ,必須使用一個合適的私鑰生成的數字證照來給程式簽名。
- 數字證照都是有有效期的,Android只是在應用程式安裝的時候才會檢查證照的有效期。如果程式已經安裝在系統中,即使證照過期也不會影響程式的正常功能。
15.Android root機制
root指的是你有許可權可以再系統上對所有檔案有 "讀" "寫" "執行"的權力。root機器不是真正能讓你的應用程式具有root許可權。它原理就跟linux下的像sudo這樣的命令。在系統的bin目錄下放個su程式並屬主是root並有suid許可權。則通過su執行的命令都具有Android root許可權。當然使用臨時使用者許可權想把su拷貝的/system/bin目錄並改屬性並不是一件容易的事情。這裡用到2個工具跟2個命令。把busybox拷貝到你有許可權訪問的目錄然後給他賦予4755許可權,你就可以用它做很多事了。
16.View、surfaceView、GLSurfaceView
View
顯示檢視,內建畫布,提供圖形繪製函式、觸屏事件、按鍵事件函式等,必須在UI主執行緒內更新畫面,速度較慢
SurfaceView
基於view檢視進行擴充的檢視類,更適合2D遊戲的開發,是view的子類,類似使用雙緩機制,在新的執行緒中更新畫面所以重新整理介面速度比view快
GLSurfaceView
基於SurfaceView檢視再次進行擴充的檢視類,專用於3D遊戲開發的檢視,是surfaceView的子類,openGL專用
AsyncTask
AsyncTask的三個泛型引數說明
- 第一個引數:傳入doInBackground()方法的引數型別
- 第二個引數:傳入onProgressUpdate()方法的引數型別
- 第三個引數:傳入onPostExecute()方法的引數型別,也是doInBackground()方法返回的型別
執行在主執行緒的方法:
onPostExecute()
onPreExecute()
onProgressUpdate(Progress...)複製程式碼
執行在子執行緒的方法:
doInBackground()複製程式碼
控制AsyncTask停止的方法:
cancel(boolean mayInterruptIfRunning)複製程式碼
AsyncTask的執行分為四個步驟
- 繼承AsyncTask。
- 實現AsyncTask中定義的下面一個或幾個方法onPreExecute()、doInBackground(Params...)、onProgressUpdate(Progress...)、onPostExecute(Result)。
- 呼叫execute方法必須在UI thread中呼叫。
- 該task只能被執行一次,否則多次呼叫時將會出現異常,取消任務可呼叫cancel。
17.Android i18n
I18n 叫做國際化。android 對i18n和L10n提供了非常好的支援。軟體在res/vales 以及 其他帶有語言修飾符的資料夾。如: values-zh 這些資料夾中 提供語言,樣式,尺寸 xml 資源。
18.NDK
- NDK是一系列工具集合,NDK提供了一系列的工具,幫助開發者迅速的開發C/C++的動態庫,並能自動將so和Java應用打成apk包。
- NDK整合了交叉編譯器,並提供了相應的mk檔案和隔離cpu、平臺等的差異,開發人員只需要簡單的修改mk檔案就可以建立出so檔案。
19.啟動一個程式,可以主介面點選圖示進入,也可以從一個程式中跳轉過去,二者有什麼區別?
通過主介面進入,就是設定預設啟動的activity。在manifest.xml檔案的activity標籤中,寫以下程式碼
<intent- filter>
<intent android:name=“android.intent.action.MAIN”>
<intent android:name=”android:intent.category.LAUNCHER”>
</intent-filter>複製程式碼
從另一個元件跳轉到目標activity,需要通過intent進行跳轉。具體
Intent intent=new Intent(this,activity.class),startActivity(intent)複製程式碼
20.記憶體溢位和記憶體洩漏有什麼區別?何時會產生記憶體洩漏?
記憶體溢位:當程式執行時所需的記憶體大於程式允許的最高記憶體,這時會出現記憶體溢位;
記憶體洩漏:在一些比較消耗資源的操作中,如果操作中記憶體一直未被釋放,就會出現記憶體洩漏。比如未關閉io,cursor。
21.sim卡的EF 檔案有何作用
sim卡就是電話卡,sim卡內有自己的作業系統,用來與手機通訊的。Ef檔案用來儲存資料的。
22.Activity的狀態有幾種?
執行
暫停
停止複製程式碼
23.讓Activity變成一個視窗
設定activity的style屬性=”@android:style/Theme.Dialog”
24.android:gravity與android:layout_gravity的區別
gravity:表示元件內元素的對齊方式
layout_gravity:相對於父類容器,該檢視元件的對齊方式
25.如何退出Activity
結束當前activity
Finish()
killProgress()
System.exit(0)複製程式碼
關閉應用程式時,結束所有的activity
可以建立一個List集合,每新建立一個activity,將該activity的例項放進list中,程式結束時,從集合中取出迴圈取出activity例項,呼叫finish()方法結束
26.如果後臺的Activity由於某原因被系統回收了,如何在被系統回收之前儲存當前狀態?
在onPuase方法中呼叫onSavedInstanceState()
27.Android中的長度單位詳解
Px:畫素
Sp與dp也是長度單位,但是與螢幕的單位密度無關。複製程式碼
28.activity,service,intent之間的關係
這三個都是android應用頻率非常的元件。Activity與service是四大核心元件。Activity用來載入佈局,顯示視窗介面,service執行後臺,沒有介面顯示,intent是activity與service的通訊使者。
29.activity之間傳遞引數,除了intent,廣播接收器,contentProvider之外,還有那些方法?
Fie:檔案儲存,推薦使用sharedPreferecnces
靜態變數。複製程式碼
30.Adapter是什麼?你所接觸過的adapter有那些?
是介面卡,用來為列表提供資料適配的。經常使用的adapter有baseadapter,arrayAdapter,SimpleAdapter,cursorAdapter,SpinnerAdapter等
31.Fragment與activity如何傳值和互動?
Fragment物件有一個getActivity的方法,通過該方法與activity互動
使用framentmentManager.findFragmentByXX可以獲取fragment物件,在activity中直接操作fragment物件複製程式碼
32.如果Listview中的資料來源發生改變,如何更新listview中的資料
使用adapter的notifyDataSetChanged方法
33.廣播接受者的生命週期?
廣播接收者的生命週期非常短。當執行onRecieve方法之後,廣播就會銷燬
在廣播接受者不能進行耗時較長的操作
在廣播接收者不要建立子執行緒。廣播接收者完成操作後,所在程式會變成空程式,很容易被系統回收複製程式碼
34.ContentProvider與sqlite有什麼不一樣的?
ContentProvider會對外隱藏內部實現,只需要關注訪問contentProvider的uri即可,contentProvider應用在應用間共享。
Sqlite操作本應用程式的資料庫。
ContentProiver可以對本地檔案進行增刪改查操作複製程式碼
35.如何儲存activity的狀態?
預設情況下activity的狀態系統會自動儲存,有些時候需要我們手動呼叫儲存。
當activity處於onPause,onStop之後,activity處於未活動狀態,但是activity物件卻仍然存在。當記憶體不足,onPause,onStop之後的activity可能會被系統摧毀。
當通過返回退出activity時,activity狀態並不會儲存。
儲存activity狀態需要重寫onSavedInstanceState()方法,在執行onPause,onStop之前呼叫onSavedInstanceState方法,onSavedInstanceState需要一個Bundle型別的引數,我們可以將資料儲存到bundle中,通過實參傳遞給onSavedInstanceState方法。
Activity被銷燬後,重新啟動時,在onCreate方法中,接受儲存的bundle引數,並將之前的資料取出。
36.Android中activity,context,application有什麼不同。
Content與application都繼承與contextWrapper,contextWrapper繼承於Context類。
Context:表示當前上下文物件,儲存的是上下文中的引數和變數,它可以讓更加方便訪問到一些資源。
Context通常與activity的生命週期是一樣的,application表示整個應用程式的物件。
對於一些生命週期較長的,不要使用context,可以使用application。
在activity中,儘量使用靜態內部類,不要使用內部類。內部裡作為外部類的成員存在,不是獨立於activity,如果記憶體中還有記憶體繼續引用到context,activity如果被銷燬,context還不會結束。
37.Service 是否在 main thread 中執行, service 裡面是否能執行耗時的操作?
預設情況service在main thread中執行,當service在主執行緒中執行,那在service中不要進行一些比較耗時的操作,比如說網路連線,檔案拷貝等。
38.Service 和 Activity 在同一個執行緒嗎
預設情況下service與activity在同一個執行緒,都在main Thread,或者ui執行緒中。
如果在清單檔案中指定service的process屬性,那麼service就在另一個程式中執行。
39.Service 裡面可以彈吐司麼
可以。
40.在 service 的生命週期方法 onstartConmand()可不可以執行網路操作?如何在 service 中執行網路操作?
可以的,就在onstartConmand方法內執行。
41.說說 ContentProvider、ContentResolver、ContentObserver 之間的關係
ContentProvider:內容提供者,對外提供資料的操作,contentProvider.notifyChanged(uir):可以更新資料
contentResolver:內容解析者,解析ContentProvider返回的資料
ContentObServer:內容監聽者,監聽資料的改變,contentResolver.registerContentObServer()複製程式碼
42.請介紹下 ContentProvider 是如何實現資料共享的
ContentProvider是一個對外提供資料的介面,首先需要實現ContentProvider這個介面,然後重寫query,insert,getType,delete,update方法,最後在清單檔案定義contentProvider的訪問uri
43.Intent 傳遞資料時,可以傳遞哪些型別資料?
基本資料型別以及對應的陣列型別
可以傳遞bundle型別,但是bundle型別的資料需要實現Serializable或者parcelable介面複製程式碼
44.Serializable 和 Parcelable 的區別?
如果儲存在記憶體中,推薦使用parcelable,使用serialiable在序列化的時候會產生大量的臨時變數,會引起頻繁的GC
如果儲存在硬碟上,推薦使用Serializable,雖然serializable效率較低
Serializable的實現:只需要實現Serializable介面,就會自動生成一個序列化id
Parcelable的實現:需要實現Parcelable介面,還需要Parcelable.CREATER變數
45.請描述一下 Intent 和 IntentFilter
Intent是元件的通訊使者,可以在元件間傳遞訊息和資料。
IntentFilter是intent的篩選器,可以對intent的action,data,catgory,uri這些屬性進行篩選,確定符合的目標元件。複製程式碼
46.什麼是IntentService?有何優點?
IntentService 是 Service 的子類,比普通的 Service 增加了額外的功能。先看 Service 本身存在兩個問題:
Service 不會專門啟動一條單獨的程式,Service 與它所在應用位於同一個程式中;
Service 也不是專門一條新執行緒,因此不應該在 Service 中直接處理耗時的任務;複製程式碼
特徵
會建立獨立的 worker 執行緒來處理所有的 Intent 請求;
會建立獨立的 worker 執行緒來處理 onHandleIntent()方法實現的程式碼,無需處理多執行緒問題;
所有請求處理完成後,IntentService 會自動停止,無需呼叫 stopSelf()方法停止 Service;
為 Service 的 onBind()提供預設實現,返回 null;
為 Service 的 onStartCommand 提供預設實現,將請求 Intent 新增到佇列中複製程式碼
使用
讓service類繼承IntentService,重寫onStartCommand和onHandleIntent實現複製程式碼
47.Android 引入廣播機制的用意
從 MVC 的角度考慮(應用程式內) 其實回答這個問題的時候還可以這樣問,android 為什麼要有那 4 大元件,現在的移動開發模型基本上也是照搬的 web 那一套 MVC 架構,只不過稍微做了修改。android 的四大元件本質上就是為了實現移動或者說嵌入式裝置上的 MVC 架構,它們之間有時候是一種相互依存的關係,有時候又是一種補充關係,引入廣播機制可以方便幾大元件的資訊和資料互動。
程式間互通訊息(例如在自己的應用程式內監聽系統來電)
效率上(參考 UDP 的廣播協議在區域網的方便性)
設計模式上(反轉控制的一種應用,類似監聽者模式)
48.ListView 如何提高其效率?
當 convertView 為空時,用 setTag()方法為每個 View 繫結一個存放控制元件的 ViewHolder 物件。當convertView 不為空, 重複利用已經建立的 view 的時候, 使用 getTag()方法獲取繫結的 ViewHolder物件,這樣就避免了 findViewById 對控制元件的層層查詢,而是快速定位到控制元件。 複用 ConvertView,使用歷史的 view,提升效率 200%
自定義靜態類 ViewHolder,減少 findViewById 的次數。提升效率 50%
非同步載入資料,分頁載入資料。
使用 WeakRefrence 引用 ImageView 物件
49.ListView 如何實現分頁載入
設定 ListView 的滾動監聽器:setOnScrollListener(new OnScrollListener{….})在監聽器中有兩個方法: 滾動狀態發生變化的方法(onScrollStateChanged)和 listView 被滾動時呼叫的方法(onScroll)
在滾動狀態發生改變的方法中,有三種狀態:手指按下移動的狀態: SCROLL_STATE_TOUCH_SCROLL:觸控滑動,慣性滾動(滑翔(flgin)狀態): SCROLL_STATE_FLING: 滑翔,靜止狀態: SCROLL_STATE_IDLE: // 靜止,對不同的狀態進行處理:
分批載入資料,只關心靜止狀態:關心最後一個可見的條目,如果最後一個可見條目就是資料介面卡(集合)裡的最後一個,此時可載入更多的資料。在每次載入的時候,計算出滾動的數量,當滾動的數量大於等於總數量的時候,可以提示使用者無更多資料了。
50.ListView 可以顯示多種型別的條目嗎
這個當然可以的,ListView 顯示的每個條目都是通過 baseAdapter 的 getView(int position,View convertView, ViewGroup parent)來展示的,理論上我們完全可以讓每個條目都是不同型別的view。
比如:從伺服器拿回一個標識為 id=1,那麼當 id=1 的時候,我們就載入型別一的條目,當 id=2的時候,載入型別二的條目。常見佈局在資訊類客戶端中可以經常看到。
除此之外 adapter 還提供了 getViewTypeCount()和 getItemViewType(int position)兩個方法。在 getView 方法中我們可以根據不同的 viewtype 載入不同的佈局檔案。
51.ListView 如何定位到指定位置
可以通過 ListView 提供的 lv.setSelection(listView.getPosition())方法。
52.如何在 ScrollView 中如何嵌入 ListView
通常情況下我們不會在 ScrollView 中巢狀 ListView。
在 ScrollView 新增一個 ListView 會導致 listview 控制元件顯示不全,通常只會顯示一條,這是因為兩個控制元件的滾動事件衝突導致。所以需要通過 listview 中的 item 數量去計算 listview 的顯示高度,從而使其完整展示。
現階段最好的處理的方式是: 自定義 ListView,過載 onMeasure()方法,設定全部顯示。
53.Manifest.xml檔案中主要包括哪些資訊?
manifest:根節點,描述了package中所有的內容。
uses-permission:請求你的package正常運作所需賦予的安全許可。
permission: 宣告瞭安全許可來限制哪些程式能你package中的元件和功能。
instrumentation:宣告瞭用來測試此package或其他package指令元件的程式碼。
application:包含package中application級別元件宣告的根節點。
activity:Activity是用來與使用者互動的主要工具。
receiver:IntentReceiver能使的application獲得資料的改變或者發生的操作,即使它當前不在執行。
service:Service是能在後臺執行任意時間的元件。
provider:ContentProvider是用來管理持久化資料併發布給其他應用程式使用的元件。複製程式碼
54.ListView 中圖片錯位的問題是如何產生的
圖片錯位問題的本質源於我們的 listview 使用了快取 convertView, 假設一種場景, 一個 listview一屏顯示九個 item,那麼在拉出第十個 item 的時候,事實上該 item 是重複使用了第一個 item,也就是說在第一個 item 從網路中下載圖片並最終要顯示的時候,其實該 item 已經不在當前顯示區域內了,此時顯示的後果將可能在第十個 item 上輸出影像,這就導致了圖片錯位的問題。所以解決辦法就是可見則顯示,不可見則不顯示。
55.Fragment 的 replace 和 add 方法的區別
Fragment 本身並沒有 replace 和 add 方法,FragmentManager才有replace和add方法。我們經常使用的一個架構就是通過RadioGroup切換Fragment,每個 Fragment 就是一個功能模組。
Fragment 的容器一個 FrameLayout,add 的時候是把所有的 Fragment 一層一層的疊加到了。FrameLayout 上了,而 replace 的話首先將該容器中的其他 Fragment 去除掉然後將當前Fragment新增到容器中。
一個 Fragment 容器中只能新增一個 Fragment 種類,如果多次新增則會報異常,導致程式終止,而 replace 則無所謂,隨便切換。因為通過 add 的方法新增的 Fragment,每個 Fragment 只能新增一次,因此如果要想達到切換效果需要通過 Fragment 的的 hide 和 show 方法結合者使用。將要顯示的 show 出來,將其他 hide起來。這個過程 Fragment 的生命週期沒有變化。
通過 replace 切換 Fragment,每次都會執行上一個 Fragment 的 onDestroyView,新 Fragment的 onCreateView、onStart、onResume 方法。基於以上不同的特點我們在使用的使用一定要結合著生命週期操作我們的檢視和資料。
56.Fragment 如何實現類似 Activity 棧的壓棧和出棧效果的?
Fragment 的事物管理器內部維持了一個雙向連結串列結構,該結構可以記錄我們每次 add 的Fragment 和 replace 的 Fragment,然後當我們點選 back 按鈕的時候會自動幫我們實現退棧操作。
57.Fragment 在你們專案中的使用
Fragment 是 android3.0 以後引入的的概念,做區域性內容更新更方便,原來為了到達這一點要把多個佈局放到一個 activity 裡面,現在可以用多 Fragment 來代替,只有在需要的時候才載入Fragment,提高效能。
Fragment 的好處:
Fragment 可以使你能夠將 activity 分離成多個可重用的元件,每個都有它自己的生命週期和UI。
Fragment 可以輕鬆得建立動態靈活的 UI 設計,可以適應於不同的螢幕尺寸。從手機到平板電腦。
Fragment 是一個獨立的模組,緊緊地與 activity 繫結在一起。可以執行中動態地移除、加入、交換等。
Fragment 提供一個新的方式讓你在不同的安卓裝置上統一你的 UI。
Fragment 解決 Activity 間的切換不流暢,輕量切換。
Fragment 替代 TabActivity 做導航,效能更好。
Fragment 在 4.2.版本中新增巢狀 fragment 使用方法,能夠生成更好的介面效果。複製程式碼
58.如何切換 fragement,不重新例項化
翻看了 Android 官方 Doc,和一些元件的原始碼,發現 replace()這個方法只是在上一個 Fragment不再需要時採用的簡便方法.
正確的切換方式是 add(),切換時 hide(),add()另一個 Fragment;再次切換時,只需 hide()當前,show()另一個。
這樣就能做到多個 Fragment 切換不重新例項化:
59.如何對 Android 應用進行效能分析
如果不考慮使用其他第三方效能分析工具的話,我們可以直接使用 ddms 中的工具,其實 ddms 工具已經非常的強大了。ddms 中有 traceview、heap、allocation tracker 等工具都可以幫助我們分析應用的方法執行時間效率和記憶體使用情況。
Traceview 是 Android 平臺特有的資料採集和分析工具,它主要用於分析 Android 中應用程式的 hotspot(瓶頸)。Traceview 本身只是一個資料分析工具,而資料的採集則需要使用 AndroidSDK 中的 Debug 類或者利用 DDMS 工具。
heap 工具可以幫助我們檢查程式碼中是否存在會造成記憶體洩漏的地方。
allocation tracker 是記憶體分配跟蹤工具
60.Android 中如何捕獲未捕獲的異常
UncaughtExceptionHandler
自 定 義 一 個 Application , 比 如 叫 MyApplication 繼 承 Application 實 現UncaughtExceptionHandler。
覆寫 UncaughtExceptionHandler 的 onCreate 和 uncaughtException 方法。 注意:上面的程式碼只是簡單的將異常列印出來。在 onCreate 方法中我們給 Thread 類設定預設異常處理 handler,如果這句程式碼不執行則一切都是白搭。在 uncaughtException 方法中我們必須新開闢個執行緒進行我們異常的收集工作,然後將系統給殺死。
在 AndroidManifest 中配置該 Application:<application android:name="com.example.uncatchexception.MyApplication"複製程式碼
Bug 收集工具 Crashlytics
Crashlytics 是專門為移動應用開發者提供的儲存和分析應用崩潰的工具。國內主要使用的是友盟做資料統計。
Crashlytics 的好處:
1.Crashlytics 不會漏掉任何應用崩潰資訊。
2.Crashlytics 可以象 Bug 管理工具那樣,管理這些崩潰日誌。
3.Crashlytics 可以每天和每週將崩潰資訊彙總發到你的郵箱,所有資訊一目瞭然。複製程式碼
61.如何將SQLite資料庫(dictionary.db檔案)與apk檔案一起釋出
把這個檔案放在/res/raw目錄下即可。res\raw目錄中的檔案不會被壓縮,這樣可以直接提取該目錄中的檔案,會生成資源id。
62.什麼是 IntentService?有何優點?
IntentService 是 Service 的子類,比普通的 Service 增加了額外的功能。先看 Service 本身存在兩個問題:
Service 不會專門啟動一條單獨的程式,Service 與它所在應用位於同一個程式中;
Service 也不是專門一條新執行緒,因此不應該在 Service 中直接處理耗時的任務;複製程式碼
IntentService 特徵
會建立獨立的 worker 執行緒來處理所有的 Intent 請求;
會建立獨立的 worker 執行緒來處理 onHandleIntent()方法實現的程式碼,無需處理多執行緒問題;
所有請求處理完成後,IntentService 會自動停止,無需呼叫 stopSelf()方法停止 Service;
為 Service 的 onBind()提供預設實現,返回 null;
為 Service 的 onStartCommand 提供預設實現,將請求 Intent 新增到佇列中;複製程式碼
63.談談對Android NDK的理解
NDK是一系列工具的集合.NDK提供了一系列的工具,幫助開發者快速開發C或C++的動態庫,並能自動將so和java應用一起打包成apk.這些工具對開發者的幫助是巨大的.NDK整合了交叉編譯器,並提供了相應的mk檔案隔離CPU,平臺,ABI等差異,開發人員只需要簡單修改 mk檔案(指出"哪些檔案需要編譯","編譯特性要求"等),就可以建立出so.
NDK可以自動地將so和Java應用一起打包,極大地減輕了開發人員的打包工作.NDK提供了一份穩定,功能有限的API標頭檔案宣告.
Google明確宣告該API是穩定的,在後續所有版本中都穩定支援當前釋出的API.從該版本的NDK中看出,這些 API支援的功能非常有限,包含有:C標準庫(libc),標準數學庫(libm ),壓縮庫(libz),Log庫(liblog).
64.AsyncTask使用在哪些場景?它的缺陷是什麼?如何解決?
AsyncTask 運用的場景就是我們需要進行一些耗時的操作,耗時操作完成後更新主執行緒,或者在操作過程中對主執行緒的UI進行更新。
缺陷:AsyncTask中維護著一個長度為128的執行緒池,同時可以執行5個工作執行緒,還有一個緩衝佇列,當執行緒池中已有128個執行緒,緩衝佇列已滿時,如果 此時向執行緒提交任務,將會丟擲RejectedExecutionException。
解決:由一個控制執行緒來處理AsyncTask的呼叫判斷執行緒池是否滿了,如果滿了則執行緒睡眠否則請求AsyncTask繼續處理。
65.Android 執行緒間通訊有哪幾種方式(重要)
共享記憶體(變數);
檔案,資料庫;
Handler;
Java 裡的 wait(),notify(),notifyAll()複製程式碼
66.請解釋下 Android 程式執行時許可權與檔案系統許可權的區別?
apk 程式是執行在虛擬機器上的,對應的是 Android 獨特的許可權機制,只有體現到檔案系統上時才
使用 linux 的許可權設定。
linux 檔案系統上的許可權
-rwxr-x--x system system 4156 2010-04-30 16:13 test.apk
代表的是相應的使用者/使用者組及其他人對此檔案的訪問許可權,與此檔案執行起來具有的許可權完全不相關。比如上面的例子只能說明 system 使用者擁有對此檔案的讀寫執行許可權;system 組的使用者對此檔案擁有讀、執行許可權;其他人對此檔案只具有執行許可權。而 test.apk 執行起來後可以幹哪些事情,跟這個就不相關了。千萬不要看 apk 檔案系統上屬於 system/system 使用者及使用者組,或者root/root 使用者及使用者組,就認為 apk 具有 system 或 root 許可權複製程式碼
Android 的許可權規則
Android 中的 apk 必須簽名
基於 UserID 的程式級別的安全機制
預設 apk 生成的資料對外是不可見的
AndroidManifest.xml 中的顯式許可權宣告複製程式碼
67.Framework 工作方式及原理,Activity 是如何生成一個 view 的,機制是什麼?
所有的框架都是基於反射 和 配置檔案(manifest)的。
普通的情況:
Activity 建立一個 view 是通過 ondraw 畫出來的, 畫這個 view 之前呢,還會呼叫 onmeasure方法來計算顯示的大小.複製程式碼
特殊情況:
Surfaceview 是直接操作硬體的,因為 或者視訊播放對幀數有要求,onDraw 效率太低,不夠使,Surfaceview 直接把資料寫到視訊記憶體。複製程式碼
68.什麼是 AIDL?如何使用?
aidl 是 Android interface definition Language 的英文縮寫,意思 Android 介面定義語言。
使用 aidl 可以幫助我們釋出以及呼叫遠端服務,實現跨程式通訊。
將服務的 aidl 放到對應的 src 目錄,工程的 gen 目錄會生成相應的介面類
我們通過 bindService(Intent,ServiceConnect,int)方法繫結遠端服務,在 bindService中 有 一 個 ServiceConnec 接 口 , 我 們 需 要 覆 寫 該 類 的onServiceConnected(ComponentName,IBinder)方法,這個方法的第二個引數 IBinder 物件其實就是已經在 aidl 中定義的介面,因此我們可以將 IBinder 物件強制轉換為 aidl 中的介面類。我們通過 IBinder 獲取到的物件(也就是 aidl 檔案生成的介面)其實是系統產生的代理物件,該代理物件既可以跟我們的程式通訊, 又可以跟遠端程式通訊, 作為一箇中間的角色實現了程式間通訊。複製程式碼
69.AIDL 的全稱是什麼?如何工作?能處理哪些型別的資料?
AIDL 全稱 Android Interface Definition Language(AndRoid 介面描述語言) 是一種介面描述語言; 編譯器可以通過 aidl 檔案生成一段程式碼,通過預先定義的介面達到兩個程式內部通訊程式跨界物件訪問的目的。需要完成兩件事情:
引入 AIDL 的相關類.;
呼叫 aidl 產生的 class複製程式碼
理論上, 引數可以傳遞基本資料型別和 String, 還有就是 Bundle 的派生類, 不過在 Eclipse 中,目前的 ADT 不支援 Bundle 做為引數。
70.Android 判斷SD卡是否存在
首先要在AndroidManifest.xml中增加SD卡訪問許可權
71.Android中任務棧的分配
Task實際上是一個Activity棧,通常使用者感受的一個Application就是一個Task。從這個定義來看,Task跟Service或者其他Components是沒有任何聯絡的,它只是針對Activity而言的。
Activity有不同的啟動模式, 可以影響到task的分配
72.SQLite支援事務嗎? 新增刪除如何提高效能?
在sqlite插入資料的時候預設一條語句就是一個事務,有多少條資料就有多少次磁碟操作 比如5000條記錄也就是要5000次讀寫磁碟操作。
新增事務處理,把多條記錄的插入或者刪除作為一個事務
73.Android中touch事件的傳遞機制是怎樣的?
1.Touch事件傳遞的相關API有dispatchTouchEvent、onTouchEvent、onInterceptTouchEvent
2.Touch事件相關的類有View、ViewGroup、Activity
3.Touch事件會被封裝成MotionEvent物件,該物件封裝了手勢按下、移動、鬆開等動作
4.Touch事件通常從Activity#dispatchTouchEvent發出,只要沒有被消費,會一直往下傳遞,到最底層的View。
5.如果Touch事件傳遞到的每個View都不消費事件,那麼Touch事件會反向向上傳遞,最終交由Activity#onTouchEvent處理.
6.onInterceptTouchEvent為ViewGroup特有,可以攔截事件.
7.Down事件到來時,如果一個View沒有消費該事件,那麼後續的MOVE/UP事件都不會再給它複製程式碼
74.描述下Handler 機制
1)Looper: 一個執行緒可以產生一個Looper物件,由它來管理此執行緒裡的MessageQueue(訊息佇列)。
2)Handler: 你可以構造Handler物件來與Looper溝通,以便push新訊息到MessageQueue裡;或者接收Looper從Message Queue取出)所送來的訊息。
3) Message Queue(訊息佇列):用來存放執行緒放入的訊息。
4)執行緒:UIthread 通常就是main thread,而Android啟動程式時會替它建立一個MessageQueue。複製程式碼
Hander持有對UI主執行緒訊息佇列MessageQueue和訊息迴圈Looper的引用,子執行緒可以通過Handler將訊息傳送到UI執行緒的訊息佇列MessageQueue中。
75.自定義view的基本流程
自定義View的屬性 編寫attr.xml檔案
在layout佈局檔案中引用,同時引用名稱空間
在View的構造方法中獲得我們自定義的屬性 ,在自定義控制元件中進行讀取(構造方法拿到attr.xml檔案值)
重寫onMesure
重寫onDraw複製程式碼
76.子執行緒發訊息到主執行緒進行更新 UI,除了 handler 和 AsyncTask,還有什麼?
用 Activity 物件的 runOnUiThread 方法更新
在子執行緒中通過 runOnUiThread()方法更新 UI:
如果在非上下文類中(Activity),可以通過傳遞上下文實現呼叫;複製程式碼
用 View.post(Runnable r)方法更新 UI
77.子執行緒中能不能 new handler?為什麼?
不能,如果在子執行緒中直接 new Handler()會丟擲異常 java.lang.RuntimeException: Can'tcreate handler inside thread that has not called
在沒有呼叫 Looper.prepare()的時候不能建立 Handler,因為在建立 Handler 的原始碼中做了如下操作
Handler 的構造方法中
78.Android 中的動畫有哪幾類,它們的特點和區別是什麼
Frame Animation(幀動畫)主要用於播放一幀幀準備好的圖片,類似GIF圖片,優點是使用簡單方便、缺點是需要事先準備好每一幀圖片;
Tween Animation(補間動畫)僅需定義開始與結束的關鍵幀,而變化的中間幀由系統補上,優點是不用準備每一幀,缺點是隻改變了物件繪製,而沒有改變View本身屬性。因此如果改變了按鈕的位置,還是需要點選原來按鈕所在位置才有效。
Property Animation(屬性動畫)是3.0後推出的動畫,優點是使用簡單、降低實現的複雜度、直接更改物件的屬性、幾乎可適用於任何物件而僅非View類,主要包括ValueAnimator和ObjectAnimator
79.如何修改 Activity 進入和退出動畫
可 以 通 過 兩 種 方 式 , 一 是 通 過 定 義 Activity 的 主 題 , 二 是 通 過 覆 寫 Activity 的overridePendingTransition 方法。
通過設定主題樣式在 styles.xml 中編輯如下程式碼:
新增 themes.xml 檔案:
在 AndroidManifest.xml 中給指定的 Activity 指定 theme。 複製程式碼
覆寫 overridePendingTransition 方法
overridePendingTransition(R.anim.fade, R.anim.hold);複製程式碼
80.Android與伺服器互動的方式中的對稱加密和非對稱加密是什麼?
對稱加密,就是加密和解密資料都是使用同一個key,這方面的演算法有DES。
非對稱加密,加密和解密是使用不同的key。傳送資料之前要先和服務端約定生成公鑰和私鑰,使用公鑰加密的資料可以用私鑰解密,反之。這方面的演算法有RSA。ssh 和 ssl都是典型的非對稱加密。
82.事件分發中的 onTouch 和 onTouchEvent 有什麼區別,又該如何使用?
這兩個方法都是在 View 的 dispatchTouchEvent 中呼叫的,onTouch 優先於 onTouchEvent執行。如果在 onTouch 方法中通過返回 true 將事件消費掉,onTouchEvent 將不會再執行。
另外需要注意的是,onTouch 能夠得到執行需要兩個前提條件,第一 mOnTouchListener 的值不能為空,第二當前點選的控制元件必須是 enable 的。因此如果你有一個控制元件是非 enable 的,那麼給它註冊 onTouch 事件將永遠得不到執行。對於這一類控制元件,如果我們想要監聽它的 touch 事件,就必須通過在該控制元件中重寫 onTouchEvent 方法來實現。
83.屬性動畫,例如一個 button 從 A 移動到 B 點,B 點還是可以響應點選事件,這個原理是什麼?
補間動畫只是顯示的位置變動,View 的實際位置未改變,表現為 View 移動到其他地方,點選事件仍在原處才能響應。而屬性動畫控制元件移動後事件相應就在控制元件移動後本身進行處理
都使用過哪些自定義控制元件
pull2RefreshListView
LazyViewPager
SlidingMenu
SmoothProgressBar
自定義組合控制元件
ToggleButton
自定義Toast複製程式碼
84.談談你在工作中是怎樣解決一個 bug
異常附近多列印 log 資訊;
分析 log 日誌,實在不行的話進行斷點除錯;
除錯不出結果,上 Stack Overflow 貼上異常資訊,請教大牛
再多看看程式碼,或者從原始碼中查詢相關資訊
實在不行就 GG 了,找師傅來解決!複製程式碼
85.嵌入式作業系統記憶體管理有哪幾種, 各有何特性
頁式,段式,段頁,用到了MMU,虛擬空間等技術
86.開發中都使用過哪些框架、平臺
EventBus(事件處理)
xUtils(網路、圖片、ORM)
JPush(推送平臺)
友盟(統計平臺)
有米(優米)(廣告平臺)
百度地圖
bmob(伺服器平臺、簡訊驗證、郵箱驗證、第三方支付)
阿里雲 OSS(雲端儲存)
ShareSDK(分享平臺、第三方登入)
Gson(解析 json 資料框架)
imageLoader (圖片處理框架)
zxing (二維碼掃描)
anroid-asyn-http(網路通訊)
DiskLruCache(硬碟快取框架)
Viatimo(多媒體播放框架)
universal-image-loader(圖片快取框架)
訊飛語音(語音識別)複製程式碼
87.談談你對 Bitmap 的理解, 什麼時候應該手動呼叫 bitmap.recycle()
Bitmap 是 android 中經常使用的一個類,它代表了一個圖片資源。 Bitmap 消耗記憶體很嚴重,如果不注意優化程式碼,經常會出現 OOM 問題,優化方式通常有這麼幾種:
使用快取;
壓縮圖片;
及時回收;複製程式碼
至於什麼時候需要手動呼叫 recycle,這就看具體場景了,原則是當我們不再使用 Bitmap 時,需要回收之。另外,我們需要注意,2.3 之前 Bitmap 物件與畫素資料是分開存放的,Bitmap 物件存在java Heap 中而畫素資料存放在 Native Memory 中, 這時很有必要呼叫 recycle 回收記憶體。 但是 2.3之後,Bitmap 物件和畫素資料都是存在 Heap 中,GC 可以回收其記憶體。
88.請介紹下 AsyncTask 的內部實現和適用的場景
AsyncTask 內部也是 Handler 機制來完成的,只不過 Android 提供了執行框架來提供執行緒池來執行相應地任務,因為執行緒池的大小問題,所以 AsyncTask 只應該用來執行耗時時間較短的任務,比如 HTTP 請求,大規模的下載和資料庫的更改不適用於 AsyncTask,因為會導致執行緒池堵塞,沒有執行緒來執行其他的任務,導致的情形是會發生 AsyncTask 根本執行不了的問題
89.Activity間通過Intent傳遞資料大小有沒有限制?
Intent在傳遞資料時是有大小限制的,這裡官方並未詳細說明,不過通過實驗的方法可以測出資料應該被限制在1MB之內(1024KB),筆者採用的是傳遞Bitmap的方法,發現當圖片大小超過1024(準確地說是1020左右)的時候,程式就會出現閃退、停止執行等異常(不同的手機反應不同),因此可以判斷Intent的傳輸容量在1MB之內。
90.你一般在開發專案中都使用什麼設計模式?如何來重構,優化你的程式碼?
較為常用的就是單例設計模式,工廠設計模式以及觀察者設計模式,
一般需要保證物件在記憶體中的唯一性時就是用單例模式,例如對資料庫操作的 SqliteOpenHelper 的物件。
工廠模式主要是為建立物件提供過渡介面,以便將建立物件的具體過程遮蔽隔離起來,達到提高靈活性的目的。
觀察者模式定義物件間的一種一對多的依賴關係,當一個物件的狀態發生改變時,所有依賴於它的物件都得到通知並被自動更新
91.Android 應用中驗證碼登陸都有哪些實現方案
從伺服器端獲取圖片
通過簡訊服務,將驗證碼傳送給客戶端複製程式碼
92.定位專案中,如何選取定位方案,如何平衡耗電與實時位置的精度?
開始定位,Application 持有一個全域性的公共位置物件,然後隔一定時間自動重新整理位置,每次重新整理成功都把新的位置資訊賦值到全域性的位置物件, 然後每個需要使用位置請求的地方都使用全域性的位置資訊進行請求。
該方案好處:請求的時候無需再反覆定位,每次請求都使用全域性的位置物件,節省時間。
該方案弊端:耗電,每隔一定時間自動重新整理位置,對電量的消耗比較大。複製程式碼
按需定位,每次請求前都進行定位。這樣做的好處是比較省電,而且節省資源,但是請求時間會變得相對較長。
93.andorid 應用第二次登入實現自動登入
前置條件是所有使用者相關介面都走 https,非使用者相關列表類資料走 http。
步驟
第一次登陸 getUserInfo 裡帶有一個長效 token,該長效 token 用來判斷使用者是否登陸和換取短 token
把長效 token 儲存到 SharedPreferences
介面請求用長效 token 換取短token,短 token 服務端可以根據你的介面最後一次請求作為標示,超時時間為一天。
所有介面都用短效 token
如果返回短效 token 失效,執行第3步,再直接當前介面
如果長效 token 失效(使用者換裝置或超過一月),提示使用者登入。複製程式碼
94.說說 LruCache 底層原理
LruCache 使用一個 LinkedHashMap 簡單的實現記憶體的快取,沒有軟引用,都是強引用。
如果新增的資料大於設定的最大值,就刪除最先快取的資料來調整記憶體。maxSize 是通過構造方法初始化的值,他表示這個快取能快取的最大值是多少。
size 在新增和移除快取都被更新值, 他通過 safeSizeOf 這個方法更新值。 safeSizeOf 預設返回 1,但一般我們會根據 maxSize 重寫這個方法,比如認為 maxSize 代表是 KB 的話,那麼就以 KB 為單位返回該項所佔的記憶體大小。
除異常外,首先會判斷 size 是否超過 maxSize,如果超過了就取出最先插入的快取,如果不為空就刪掉,並把 size 減去該項所佔的大小。這個操作將一直迴圈下去,直到 size 比 maxSize 小或者快取為空。
95.jni 的呼叫過程?
安裝和下載 Cygwin,下載 Android NDK。
ndk 專案中 JNI 介面的設計。
使用 C/C++實現本地方法。
JNI 生成動態連結庫.so 檔案。
將動態連結庫複製到 java 工程,在 java 工程中呼叫,執行 java 工程即可。複製程式碼
96.一條最長的簡訊息約佔多少byte?
中文70(包括標點),英文160,160個位元組。
98.即時通訊是是怎麼做的?
使用asmark 開源框架實現的即時通訊功能.該框架基於開源的 XMPP 即時通訊協議,採用 C/S 體系結構,通過 GPRS 無線網路用 TCP 協議連線到伺服器,以架設開源的Openfn'e 伺服器作為即時通訊平臺。
客戶端基於 Android 平臺進行開發。負責初始化通訊過程,進行即時通訊時,由客戶端負責向伺服器發起建立連線請求。系統通過 GPRS 無線網路與 Internet 網路建立連線,通過伺服器實現與Android 客戶端的即時通訊腳。
伺服器端則採用 Openfire 作為伺服器。 允許多個客戶端同時登入並且併發的連線到一個伺服器上。伺服器對每個客戶端的連線進行認證,對認證通過的客戶端建立會話,客戶端與伺服器端之間的通訊就在該會話的上下文中進行。
99.怎樣對 android 進行優化?
對 listview 的優化。
對圖片的優化。
對記憶體的優化。
具體一些措施
儘量不要使用過多的靜態類 static
資料庫使用完成後要記得關閉 cursor
廣播使用完之後要登出複製程式碼
100.如果有個100M大的檔案,需要上傳至伺服器中,而伺服器form表單最大隻能上傳2M,可以用什麼方法。
首先來說使用http協議上傳資料,特別在android下,跟form沒什麼關係。
傳統的在web中,在form中寫檔案上傳,其實瀏覽器所做的就是將我們的資料進行解析組拼成字串,以流的方式傳送到伺服器,且上傳檔案用的都是POST方式,POST方式對大小沒什麼限制。
回到題目,可以說假設每次真的只能上傳2M,那麼可能我們只能把檔案截斷,然後分別上傳了,斷點上傳。