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"?>

<animation-listxmlns: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"?>

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大組件

1. Activity:

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

2. BroadCast Receiver:

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

3. Content Provider:

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

4. 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格式將數據存儲到設備中。只能在同一個包內使用,不能在不同的包之間使用。

2. 文件存儲數據

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

3. SQLite數據庫存儲數據

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

4. 使用ContentProvider存儲數據

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

5. 網絡存儲數據

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

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模式啟動的。

2. singleTop 棧頂復用模式

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

3. singleTask 棧內復用模式

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

4. singleInstance 單實例模式

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

11.廣播注冊

首先寫一個類要繼承BroadCastReceiver

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

<receiveandroid:name=".BroadCastReceiverDemo">

<intent-filter>

<actionandroid:name="android.provider.Telephony.SMS_RECEIVED">

</intent-filter>

</receiver>

第二種:使用代碼進行注冊如:

IntentFilter filter=newIntentFilter("android.provider.Telephony.SMS_RECEIVED");

BroadCastReceiverDemo receiver=newBroadCastReceiver();

registerReceiver(receiver,filter);

兩種注冊類型的區別是:

a.第一種是常駐型廣播,也就是說當應用程序關閉后,如果有信息廣播來,程序也會被系統調用自動運行。

b.第二種不是常駐廣播,也就是說廣播跟隨程序的生命周期。

12.Android中的ANR

ANR的全稱application not responding應用程序未響應。

ANR 類型最長ANR時間

事件分發(點擊輸入等):5s

BroadcastReceiver10s

Service20s`

超出執行時間就會產生ANR。注意:ANR是系統拋出的異常,程序是捕捉不了這個異常的。

解決方法:

運行在主線程里的任何方法都盡可能少做事情。特別是,Activity應該在它的關鍵生命周期方法(如onCreate()和onResume())里盡可能少的去做創建操作。可以采用重新開啟子線程的方式,然后使用Handler+Message的方式做一些操作,比如更新主線程中的ui等。

應用程序應該避免在·BroadcastReceiver·里做耗時的操作或計算。但不再是在子線程里做這些任務(因為 BroadcastReceiver的生命周期短),替代的是,如果響應Intent廣播需要執行一個耗時的動作的話,應用程序應該啟動一個Service。

13.ListView優化

1. convertView重用

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

2. ViewHolder優化

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

3. 減少Item View的布局層級

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

4. adapter中的getView方法盡量少使用邏輯

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

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

7. 使用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(booleanmayInterruptIfRunning)

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>

<intentandroid:name=“android.intent.action.MAIN”>

<intentandroid:name=”android:intent.category.LAUNCHER”>

</intent-filter>

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

Intent intent=newIntent(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>

<actionandroid:name="android.intent.action.MAIN"/>

<categoryandroid: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是否掛載

*/

publicstaticbooleanisSDCardMount(){

returnEnvironment.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,那么可能我們只能把文件截斷,然后分別上傳了,斷點上傳。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容