Android開發者面試一百題

Android是一種基於Linux的自由及開放源代碼的操作系統,主要使用於移動設備,如智能手機和平板電腦,由Google公司和開放手機聯盟領導及開發。這裏會不斷收集和更新Android基礎相關的面試題,目前已收集100題。

1.Android系統的架構

應用程序

Android會同一系列核心應用程序包一起發佈,該應用程序包包括Email客戶端,SMS短消息程序,日曆,地圖,瀏覽器,聯繫人管理程序等。所有的應用程序都是使用JAVA語言編寫的。

應用程序框架

開發人員可以完全訪問核心應用程序所使用的API框架(android.jar)。該應用程序的架構設計簡化了組件的重用;任何一個應用程序都可以發佈它的功能塊並且任何其它的應用程序都可以使用其所發佈的功能塊。

系統運行庫

Android包含一些C/C++庫,這些庫能被Android系統中不同的組件使用。它們通過Android 應用程序框架爲開發者提供服務。

Linux 內核

Android的核心繫統服務依賴於 Linux 內核,如安全性,內存管理,進程管理, 網絡協議棧和驅動模型。 Linux 內核也同時作爲硬件和軟件棧之間的抽象層。

2.Activity的生命週期

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的生命週期
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"?> 補間動畫

補間動畫又可以分爲四種形式,分別是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”] >








屬性動畫

屬性動畫,顧名思義它是對於對象屬性的動畫。因此,所有補間動畫的內容,都可以通過屬性動畫實現。屬性動畫的運行機制是通過不斷地對值進行操作來實現的,而初始值和結束值之間的動畫過渡就是由ValueAnimator這個類來負責計算的。它的內部使用一種時間循環的機制來計算值與值之間的動畫過渡,我們只需要將初始值和結束值提供給ValueAnimator,並且告訴它動畫所需運行的時長,那麼ValueAnimator就會自動幫我們完成從初始值平滑地過渡到結束值這樣的效果。除此之外,ValueAnimator還負責管理動畫的播放次數、播放模式、以及對動畫設置監聽器等。

6.Android中4大組件

  1. Activity:

Activity是Android程序與用戶交互的窗口,是Android構造塊中最基本的一種,它需要爲保持各界面的狀態,做很多持久化的事情,妥善管理生命週期以及一些跳轉邏輯。

  1. BroadCast Receiver:

接受一種或者多種Intent作觸發事件,接受相關消息,做一些簡單處理,轉換成一條Notification,統一了Android的事件廣播模型。

  1. Content Provider:

是Android提供的第三方應用數據的訪問方案,可以派生Content Provider類,對外提供數據,可以像數據庫一樣進行選擇排序,屏蔽內部數據的存儲細節,向外提供統一的接口模型,大大簡化上層應用,對數據的整合提 供了更方便的途徑。

  1. 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協議

簡介:輕量級的、基於代理的“發佈/訂閱”模式的消息傳輸協議。
優點:協議簡潔、小巧、可擴展性強、省流量、省電,目前已經應用到企業領域。
缺點:不夠成熟、實現較複雜、服務端組件rsmb不開源,部署硬件成本較高。
方案4、使用HTTP輪循方式

簡介:定時向HTTP服務端接口(Web Service API)獲取最新消息。
優點:實現簡單、可控性強,部署硬件成本低。
缺點:實時性差。
9.Android的數據存儲

  1. 使用SharedPreferences存儲數據

它是Android提供的用來存儲一些簡單配置信息的一種機制,採用了XML格式將數據存儲到設備中。只能在同一個包內使用,不能在不同的包之間使用。

  1. 文件存儲數據

文件存儲方式是一種較常用的方法,在Android中讀取/寫入文件的方法,與Java中實現I/O的程序是完全一樣的,提供了openFileInput()和openFileOutput()方法來讀取設備上的文件。

  1. SQLite數據庫存儲數據

SQLite是Android所帶的一個標準的數據庫,它支持SQL語句,它是一個輕量級的嵌入式數據庫。

  1. 使用ContentProvider存儲數據

主要用於應用程序之間進行數據交換,從而能夠讓其他的應用保存或讀取此Content Provider的各種數據類型。

  1. 網絡存儲數據

通過網絡上提供給我們的存儲空間來上傳(存儲)和下載(獲取)我們存儲在網絡空間中的數據信息。

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種啓動模式

  1. 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模式啓動的。

  1. singleTop 棧頂複用模式

假如activity A啓動了 activity B,就會判斷 A 所在的任務棧棧頂是否是 B 的實例。如果是,則不創建新的 activity B 實例而是直接引用這個棧頂實例,同時 onNewIntent 方法會被回調,通過該方法的參數可以取得當前請求的信息;如果不是,則創建新的 activity B實例。

  1. singleTask 棧內複用模式

在第一次啓動這個 Activity時,系統便會創建一個新的任務,並且初始化Activity的實例,放在新任務的底部。不過需要滿足一定條件的。那就是需要設置taskAffinity屬性。前面也說過了,taskAffinity 屬性是和singleTask模式搭配使用的。

  1. singleInstance 單實例模式

這個是singleTask 模式的加強版,它除了具有singleTask模式的所有特性外,它還有一點獨特的特性,那就是此模式的Activity 只能單獨地位於一個任務棧,不與其他 Activity共存於同一個任務棧。

11.廣播註冊

首先寫一個類要繼承BroadCastReceiver

第一種:在清單文件中聲明,添加

第二種:使用代碼進行註冊如:
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應用程序未響應。

ANR 類型 最長ANR時間
事件分發(點擊輸入等): 5s
BroadcastReceiver 10s
Service 20s`
超出執行時間就會產生ANR。注意:ANR是系統拋出的異常,程序是捕捉不了這個異常的。

解決方法:

運行在主線程裏的任何方法都儘可能少做事情。特別是,Activity應該在它的關鍵生命週期方法 (如onCreate()和onResume())裏儘可能少的去做創建操作。可以採用重新開啓子線程的方式,然後使用Handler+Message的方式做一些操作,比如更新主線程中的ui等。
應用程序應該避免在·BroadcastReceiver·裏做耗時的操作或計算。但不再是在子線程裏做這些任務(因爲 BroadcastReceiver的生命週期短),替代的是,如果響應Intent廣播需要執行一個耗時的動作的話,應用程序應該啓動一個 Service。
13.ListView優化

  1. convertView重用

利用好convertView來重用View,切忌每次 getView() 都新建。ListView的核心原理就是重用View,如果重用view 不改變寬高,重用View可以減少重新分配緩存造成的內存頻繁分配/回收;

  1. ViewHolder優化

使用ViewHolder的原因是findViewById方法耗時較大,如果控件個數過多,會嚴重影響性能,而使用ViewHolder主要是爲了可以省去這個時間。通過setTag,getTag直接獲取View。

  1. 減少Item View的佈局層級

這是所有Layout都必須遵循的,佈局層級過深會直接導致View的測量與繪製浪費大量的時間。

  1. adapter中的getView方法儘量少使用邏輯

  2. 圖片加載採用三級緩存,避免每次都要重新加載。

  3. 嘗試開啓硬件加速來使ListView的滑動更加流暢。

  4. 使用 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標籤中,寫以下代碼

從另一個組件跳轉到目標 activity ,需要通過 intent 進行跳轉。具體

Intent intent=new Intent(this,activity.class),startActivity(intent)
20.內存溢出和內存泄漏有什麼區別?何時會產生內存泄漏?

內存溢出:

當程序運行時所需的內存大於程序允許的最高內存,這時會出現內存溢出;

內存泄漏:

在一些比較消耗資源的操作中,如果操作中內存一直未被釋放,就會出現內存泄漏。比如未關閉io,cursor。

21.sim卡的EF 文件有何作用

sim卡就是電話卡,sim卡內有自己的操作系統,用來與手機通訊的。Ef文件用來存儲數據的。

22.Activity的狀態有幾種?

主要有以下三種狀態:

1.運行
2.暫停
3.停止

23.讓Activity變成一個窗口

設置activity的style屬性=”@android:style/Theme.Dialog”

    <activity
        android:name=".CondorMainActivity"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.Dialog" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

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之外,還有那些方法?

File:
文件存儲,推薦使用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應用在app間共享。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 裏面可以彈Toast麼

可以。

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 傳遞數據時,可以傳遞哪些類型數據?

1.基本數據類型以及對應的數組類型

2.可以傳遞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本身存在兩個問題:

1.Service 不會專門啓動一條單獨的進程,Service與它所在應用位於同一個進程中;
2.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 線程間通信有哪幾種方式(重要)

1.共享內存(變量)
2.文件,數據庫
3.Handler
4.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中 有 一 個 ServiceConnect 接 口 , 我 們 需 要 覆 寫 該 類 的onServiceConnected(ComponentName,IBinder)方法,這個方法的第二個參數IBinder對象其實就是已經在 aidl中定義的接口,因此我們可以將IBinder 對象強制轉換爲aidl中的接口類。我們通過IBinder 獲取到的對象(也就是 aidl文件生成的接口)其實是系統產生的代理對象,該代理對象既可以跟我們的進程通信, 又可以跟遠程進程通信, 作爲一箇中間的角色實現了進程間通信。

69.AIDL 的全稱是什麼?如何工作?能處理哪些類型的數據?

AIDL全稱 Android Interface Definition Language(AndRoid 接口描述語言) 是一種接口描述語言; 編譯器可以通過 aidl文件生成一段代碼,通過預先定義的接口達到兩個進程內部通信進程跨界對象訪問的目的。需要完成兩件事情:

1.引入AIDL 的相關類.;
2.調用aidl產生的 class

理論上, 參數可以傳遞基本數據類型和 String, 還有就是 Bundle的派生類, 不過在Eclipse中,目前的 ADT 不支持Bundle 做爲參數。

70.Android 判斷SD卡是否存在

/**
* 判斷SD是否掛載
*/
public static boolean isSDCardMount() {
return Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED);
}
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取出所送來的消息。

Message Queue(消息隊列):
用來存放線程放入的消息。

4)線程:

UIthread通常就是main thread,而Android啓動程序時會替它建立一個MessageQueue。

Hander持有對UI主線程消息隊列MessageQueue和消息循環Looper的引用,子線程可以通過Handler將消息發送到UI線程的消息隊列MessageQueue中。

75.自定義view的基本流程

1.自定義View的屬性 編寫attr.xml文件
2.在layout佈局文件中引用,同時引用命名空間
3.在View的構造方法中獲得我們自定義的屬性 ,在自定義控件中進行讀取(構造方法拿到attr.xml文件值)
4.重寫onMesure
5.重寫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

78.Android 中的動畫有哪幾類,它們的特點和區別是什麼

Frame Animation(幀動畫)

主要用於播放一幀幀準備好的圖片,類似GIF圖片,優點是使用簡單方便、缺點是需要事先準備好每一幀圖片;

Tween Animation(補間動畫)

僅需定義開始與結束的關鍵幀,而變化的中間幀由系統補上,優點是不用準備每一幀,缺點是隻改變了對象繪製,而沒有改變View本身屬性。因此如果改變了按鈕的位置,還是需要點擊原來按鈕所在位置纔有效。

Property Animation(屬性動畫)

是3.0後推出的動畫,優點是使用簡單、降低實現的複雜度、直接更改對象的屬性、幾乎可適用於任何對象而僅非View類,主要包括ValueAnimator和ObjectAnimator

79.如何修改 Activity 進入和退出動畫

可以通過兩種方式

一 是通過定義 Activity的主題
通過設置主題樣式在styles.xml中編輯如下代碼:

添加 themes.xml 文件:
在 AndroidManifest.xml 中給指定的 Activity 指定 theme。
二 是通過覆寫 Activity 的overridePendingTransition 方法。

覆寫 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 移動到其他地方,點擊事件仍在原處才能響應。而屬性動畫控件移動後事件相應就在控件移動後本身進行處理

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問題,優化方式通常有這麼幾種:
1.使用緩存;
2.壓縮圖片;
3.及時回收;

至於什麼時候需要手動調用 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,那麼可能我們只能把文件截斷,然後分別上傳了,斷點上傳。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章