1. 程式人生 > >Android面試題總結加強版(三)

Android面試題總結加強版(三)

自己總結的最強android應用面試題集

26.如果後臺的Activity由於某原因被系統回收了,如何在被系統回收之前儲存當前狀態?

當你的程式中某一個Activity A 在執行時中,主動或被動地執行另一個新的Activity B 
這個時候A會執行

Java程式碼

public void onSaveInstanceState(Bundle outState) {    super.onSaveInstanceState(outState);    outState.putLong("id", 1234567890);}  

B 完成以後又會來找A, 這個時候就有兩種情況,一種是A被回收,一種是沒有被回收,被回
收的A就要重新呼叫onCreate()方法,不同於直接啟動的是這回onCreate()裡是帶上引數savedInstanceState,沒被收回的就還是onResume就好了。

savedInstanceState是一個Bundle物件,你基本上可以把他理解為系統幫你維護的一個Map物件。在onCreate()裡你可能會 用到它,如果正常啟動onCreate就不會有它,所以用的時候要判斷一下是否為空。

Java程式碼

if(savedInstanceState != null){  
     long id = savedInstanceState.getLong("id");  
}  

就像官方的Notepad教程 裡的情況,你正在編輯某一個note,突然被中斷,那麼就把這個note的id記住,再起來的時候就可以根據這個id去把那個note取出來,程式就完整 一些。這也是看你的應用需不需要儲存什麼,比如你的介面就是讀取一個列表,那就不需要特殊記住什麼,哦, 沒準你需要記住滾動條的位置...

27.如何退出Activity

對於單一Activity的應用來說,退出很簡單,直接finish()即可。當然,也可以用killProcess()System.exit()這樣的方法。現提供幾個方法,供參考:
1、拋異常強制退出:該方法通過拋異常,使程式Force Close。驗證可以,但是,需要解決的問題是,如何使程式結束掉,而不彈出Force Close的視窗。
2、記錄開啟的Activity:每開啟一個Activity,就記錄下來。在需要退出時,關閉每一個Activity即可。
3、傳送特定廣播:在需要結束應用時,傳送一個特定的廣播,每個Activity收到廣播後,關閉即可。
4、遞迴退出在開啟新的

Activity時使用startActivityForResult,然後自己加標誌,在onActivityResult中處理,遞迴關閉。除了第一個,都是想辦法把每一個Activity都結束掉,間接達到目的。但是這樣做同樣不完美。你會發現,如果自己的應用程式對每一個Activity都設定了nosensor,在兩個Activity結束的間隙,sensor可能有效了。但至少,我們的目的達到了,而且沒有影響使用者使用。為了程式設計方便,最好定義一個Activity基類,處理這些共通問題。

28.請解釋下在單執行緒模型中MessageHandlerMessage QueueLooper之間的關係。

Message Queue(訊息佇列):用來存放通過Handler釋出的訊息,通常附屬於某一個建立它的執行緒,可以通過Looper.myQueue()得到當前執行緒的訊息佇列
   Handler:可以釋出或者處理一個訊息或者操作一個Runnable,通過Handler釋出訊息,訊息將只會傳送到與它關聯的訊息佇列,然也只能處理該訊息佇列中的訊息
   Looper:是Handler和訊息佇列之間通訊橋樑,程式元件首先通過Handler把訊息傳遞給LooperLooper把訊息放入佇列。Looper也把訊息佇列裡的訊息廣播給所有的
    HandlerHandler接受到訊息後呼叫handleMessage進行處理
   Message:訊息的型別,在Handler類中的handleMessage方法中得到單個的訊息進行處理.

29.你如何評價Android系統?優缺點。

答:優點:1、學習的開源性
   2、軟體相容性比較好
   3、軟體發展迅速
   4、介面佈局好
   缺點:1、版本過多
         2、先有軟體少  3、商務效能差

30.談談android資料儲存方式。

Android提供了5種方式儲存資料:
1)使用SharedPreferences儲存資料;它是Android提供的用來儲存一些簡單配置資訊的一種機制,採用了XML格式將資料儲存到裝置中。只能在同一個包內使用,不能在不同的包之間使用。
2)檔案儲存資料;檔案儲存方式是一種較常用的方法,在Android中讀取/寫入檔案的方法,與Java中實現I/O的程式是完全一樣的,提供了openFileInput()openFileOutput()方法來讀取裝置上的檔案。
3SQLite資料庫儲存資料;SQLiteAndroid所帶的一個標準的資料庫,它支援SQL語句,它是一個輕量級的嵌入式資料庫。
4)使用ContentProvider儲存資料;主要用於應用程式之間進行資料交換,從而能夠讓其他的應用儲存或讀取此Content Provider的各種資料型別。
5)網路儲存資料;通過網路上提供給我們的儲存空間來上傳(儲存)和下載(獲取)我們儲存在網路空間中的資料資訊。

31. AndroidActivity, Intent, Content Provider, Service各有什麼區別。

Activity: 活動,是最基本的android應用程式元件。一個活動就是一個單獨的螢幕,每一個活動都被實現為一個獨立的類,並且從活動基類繼承而來。
Intent: 意圖,描述應用想幹什麼。最重要的部分是動作和動作對應的資料。
Content Provider:內容提供器,android應用程式能夠將它們的資料儲存到檔案、SQLite資料庫中,甚至是任何有效的裝置中。當你想將你的應用資料和其他應用共享時,內容提供器就可以發揮作用了。
Service:服務,具有一段較長生命週期且沒有使用者介面的程式。

32.View, surfaceView, GLSurfaceView有什麼區別。

view是最基礎的,必須在UI主執行緒內更新畫面,速度較慢。
SurfaceView view的子類,類似使用雙緩機制,在新的執行緒中更新畫面所以重新整理介面速度比view
GLSurfaceView SurfaceView的子類,opengl 專用的

33.Manifest.xml檔案中主要包括哪些資訊?

manifest:根節點,描述了package中所有的內容。
uses-permission:請求你的package正常運作所需賦予的安全許可。
permission: 聲明瞭安全許可來限制哪些程式能你package中的元件和功能。
instrumentation:聲明瞭用來測試此package或其他package指令元件的程式碼。
application:包含packageapplication級別元件宣告的根節點。
activityActivity是用來與使用者互動的主要工具。
receiverIntentReceiver能使的application獲得資料的改變或者發生的操作,即使它當前不在執行。
serviceService是能在後臺執行任意時間的元件。
providerContentProvider是用來管理持久化資料併發布給其他應用程式使用的元件。

34.根據自己的理解描述下Android數字簽名。

(1)所有的應用程式都必須有數字證書,Android系統不會安裝一個沒有數字證書的應用程式
(2)Android程式包使用的數字證書可以是自簽名的,不需要一個權威的數字證書機構簽名認證
(3)如果要正式釋出一個Android ,必須使用一個合適的私鑰生成的數字證書來給程式簽名,而不能使用adt外掛或者ant工具生成的除錯證書來發布。
(4)數字證書都是有有效期的,Android只是在應用程式安裝的時候才會檢查證書的有效期。如果程式已經安裝在系統中,即使證書過期也不會影響程式的正常功能。

35. AIDL的全稱是什麼?如何工作?能處理哪些型別的資料?

AIDL全稱Android Interface Definition LanguageAndRoid介面描述語言)是一種藉口描述語言編譯器可以通過aidl檔案生成一段程式碼,通過預先定義的介面達到兩個程序內部通訊程序跨界物件訪問的目的.AIDLIPC的機制和COMCORBA類似是基於介面的,但它是輕量級的。它使用代理類在客戶端和實現層間傳遞值如果要使用AIDL, 需要完成2件事情: 1. 引入AIDL的相關類.; 2. 呼叫aidl產生的class.理論上引數可以傳遞基本資料型別和String, 還有就是Bundle的派生類不過在Eclipse,目前的ADT不支援Bundle做為引數,
具體實現步驟如下:

1、建立AIDL檔案在這個檔案裡面定義介面該介面定義了可供客戶端訪問的方法和屬性。

2、編譯AIDL檔案Ant的話可能需要手動使用Eclipse plugin的話,可以根據adil檔案自動生產java檔案並編譯不需要人為介入.

3、在Java檔案中實現AIDL中定義的介面編譯器會根據AIDL介面產生一個JAVA介面。這個介面有一個名為Stub的內部抽象類,它繼承擴充套件了介面並實現了遠端呼叫需要的幾個方法。接下來就需要自己去實現自定義的幾個介面了.
4、向客戶端提供介面ITaskBinder, 如果寫的是service,擴充套件該Service並重載onBind ()方法來返回一個實現上述介面的類的例項。
5、在伺服器端回撥客戶端的函式前提是當客戶端獲取的IBinder介面的時候,要去註冊回撥函式只有這樣伺服器端才知道該呼叫那些函式

AIDL語法很簡單,可以用來宣告一個帶一個或多個方法的介面,也可以傳遞引數和返回值。 由於遠端呼叫的需要這些引數和返回值並不是任何型別.下面是些AIDL支援的資料型別:

1. 不需要import宣告的簡單Java程式語言型別(int,boolean)

2. String, CharSequence不需要特殊宣告

3. List, MapParcelables型別這些型別內所包含的資料成員也只能是簡單資料型別, String等其他比支援的型別.

(另外我沒嘗試Parcelables, Eclipse+ADT下編譯不過或許以後會有所支援).

實現介面時有幾個原則:

.丟擲的異常不要返回給呼叫者跨程序拋異常處理是不可取的.

.IPC呼叫是同步的。如果你知道一個IPC服務需要超過幾毫秒的時間才能完成地話,你應該避免在Activity的主執行緒中呼叫。也就是IPC呼叫會掛起應用程式導致介面失去響應這種情況應該考慮單起一個執行緒來處理.

.不能在AIDL介面中宣告靜態屬性。

IPC的呼叫步驟:

1. 宣告一個介面型別的變數,該介面型別在.aidl檔案中定義。

2. 實現ServiceConnection

3. 呼叫ApplicationContext.bindService(),並在ServiceConnection實現中進行傳遞.

4. ServiceConnection.onServiceConnected()實現中,你會接收一個IBinder例項(被呼叫的Service). 呼叫

YourInterfaceName.Stub.asInterface((IBinder)service)將引數轉換為YourInterface型別。

5. 呼叫介面中定義的方法。你總要檢測到DeadObjectException異常,該異常在連線斷開時被丟擲。它只會被遠端方法丟擲。

6. 斷開連線,呼叫介面例項中的ApplicationContext.unbindService()
參考:http://buaadallas.blog.51cto.com/399160/372090

36.android:gravityandroid:layout_gravity的區別

LinearLayout有兩個非常相似的屬性:android:gravityandroid:layout_gravity。他們的區別在 於:android:gravity用於設定View元件的對齊方式,而android:layout_gravity用於設定Container元件的 對齊方式。

舉個例子,我們可以通過設定android:gravity="center"來讓EditText中的文字在EditText元件中居中顯示;同 時我們設定EditTextandroid:layout_gravity="right"來讓EditText元件在LinearLayout中居中 顯示。來實踐以下:

正如我們所看到的,在EditText中,其中的文字已經居中顯示了,而EditText元件自己也對齊到了LinearLayout的右側。

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 
    <EditText 
        android:layout_width="wrap_content" 
        android:gravity="center" 
        android:layout_height="wrap_content" 
        android:text="one" 
        android:layout_gravity="right"/> 
</LinearLayout>



這兩個屬性也可以用於 Framlayout Textview 等等,表示的意思大同小異

37.paddingmargin的區別

padding填充的意思,指的是view中的contentview邊緣的距離,類似文字中的indent
margin表示的是view的左邊緣與parent view的左邊緣的距離
margin一般用來描述控制元件間位置關係,而padding一般描述控制元件內容和控制元件的位置關係。

簡單,padding是站在父 view的角度描述問題,它規定它裡面的內容必須與這個父view邊界的距離。margin則是站在自己的角度描述問題,規定自己和其他(上下左右)的 view之間的距離,如果同一級只有一個view,那麼它的效果基本上就和padding一樣了。例如我的XML layout程式碼如下:

<?xml version="1.0" encoding="utf-8"?>  
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:orientation="vertical"  
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent"  
    android:paddingLeft="10dip"  
    android:paddingRight="10dip"  
    android:paddingTop="10dip"  
    android:paddingBottom="10dip"  
    >  
<TextView    
    android:layout_width="wrap_content"   
    android:layout_height="wrap_content"   
    android:background="#FF0000"  
    android:text="@string/hello"  
    android:paddingLeft="50dip"  
    android:paddingRight="50dip"  
    android:paddingTop="50dip"  
    android:paddingBottom="50dip"  
    android:layout_marginBottom="10dip"  
    />  
    <TextView    
    android:layout_width="wrap_content"   
    android:layout_height="wrap_content"   
    android:background="#FF0000"  
    android:text="@string/hello"  
    android:paddingLeft="50dip"  
    android:paddingRight="50dip"  
    android:paddingTop="50dip"  
    android:paddingBottom="50dip"  
    android:layout_marginBottom="10dip"  
    />  
    <TextView    
    android:layout_width="wrap_content"   
    android:layout_height="wrap_content"   
    android:background="#FF0000"  
    android:text="@string/hello"  
    android:paddingLeft="50dip"  
    android:paddingRight="50dip"  
    android:paddingTop="50dip"  
    android:paddingBottom="50dip"  
    android:layout_marginBottom="10dip"  
    />  
    <TextView    
    android:layout_width="wrap_content"   
    android:layout_height="wrap_content"   
    android:background="#FF0000"  
    android:text="@string/hello"  
    android:paddingLeft="50dip"  
    android:paddingRight="50dip"  
    android:paddingTop="50dip"  
    android:paddingBottom="50dip"  
    android:layout_marginBottom="10dip"  
    />  
</LinearLayout>  

 那麼我會得到如下的效果,圖上已經很明確的標出來區別咯。

38. 註冊廣播接收者兩種方式的區別

  現在我們就來實現一個簡單的廣播程式。Android提供了兩種註冊廣播接受者的形式,分別是在程式中動態註冊和在xml中指定。他們之間的區別就是作用 的範圍不同,程式動態註冊的接收者只在程式執行過程中有效,而在xml註冊的接收者不管你的程式有沒有啟動有會起作用。

39.Dalvik基於JVM的改進

1.幾個class變為一個dexconstant pool,省記憶體

2.Zygotecopy-on-write shared,省記憶體,省cpu,省電

3.基於暫存器的bytecode,省指令,省cpu,省電

4.Trace-based JIT,cpu,省電,省記憶體

40.android中有哪幾種解析xml的類,官方推薦哪種?以及它們的原理和區別.

Ø DOM解析

    優點:

1.XML樹在記憶體中完整儲存,因此可以直接修改其資料和結構. 

2.可以通過該解析器隨時訪問XML樹中的任何一個節點. 

3.DOM解析器的API在使用上也相對比較簡單.

缺點:如果XML文件體積比較大時,將文件讀入記憶體是非常消耗系統資源的.

使用場景:DOM 是用與平臺和語言無關的方式表示 XML 文件的官方 W3C 標準.DOM 是以層次結構組織的節點的集合.這個層次結構允許開發人員在樹中尋找特定資訊.分析該結構通常需要載入整個文件和構造層次結構,然後才能進行任何工作.DOM是基於物件層次結構的.

Ø SAX解析

優點:

SAX 對記憶體的要求比較低,因為它讓開發人員自己來決定所要處理的標籤.特別是當開發人員只需要處理文件中所包含的部分資料時,SAX 這種擴充套件能力得到了更好的體現.

缺點:

用SAX方式進行XML解析時,需要順序執行,所以很難訪問到同一文件中的不同資料.此外,在基於該方式的解析編碼過程也相對複雜.

使用場景:

對於含有資料量十分巨大,而又不用對文件的所有資料進行遍歷或者分析的時候,使用該方法十分有效.該方法不用將整個文件讀入記憶體,而只需讀取到程式所需的文件標籤處即可.

Ø Xmlpull解析

android SDK提供了xmlpull api,xmlpull和sax類似,是基於流(stream)操作檔案,然後根據節點事件回撥開發者編寫的處理程式.因為是基於流的處理,因此xmlpull和sax都比較節約記憶體資源,不會象dom那樣要把所有節點以對橡樹的形式展現在記憶體中.xmlpull比sax更簡明,而且不需要掃描完整個流.

41.Android系統中GC什麼情況下會出現記憶體洩露呢?

出現情況:
1. 資料庫的cursor沒有關閉
2.構造adapter時,沒有使用快取contentview
   衍生listview的優化問題-----減少建立view的物件,充分使用contentview,可以使用一靜態類來優化處理getview的過程/
3.Bitmap物件不使用時採用recycle()釋放記憶體
4.activity中的物件的生命週期大於activity
除錯方法: DDMS==> HEAPSZIE==>dataobject==>[Total Size]

42.談談對Android NDK的理解

NDK 全稱: Native Development Kit 

2.誤解 
    誤解一: NDK 釋出之前, Android 不支援進行 C 開發 
    在Google 中搜索 “NDK” ,很多 “Android 終於可以使用 C++ 開發 ” 之類的標題,這是一種對 Android 平臺程式設計方式的誤解.其實, Android 平臺從誕生起,就已經支援 C . C++ 開發.眾所周知, Android 的 SDK 基於 Java 實現,這意味著基於 Android SDK 進行開發的第三方應用都必須使用 Java 語言.但這並不等同於 “ 第三方應用只能使用 Java” .在 Android SDK 首次釋出時, Google 就宣稱其虛擬機器 Dalvik 支援 JNI 程式設計方式,也就是第三方應用完全可以通過 JNI 呼叫自己的 C 動態庫,即在 Android 平臺上, “Java+C” 的程式設計方式是一直都可以實現的.

 當然這種誤解的產生是有根源的:在Android SDK 文件裡,找不到任何 JNI 方面的幫助.即使第三方應用開發者使用 JNI 完成了自己的 C 動態連結庫( so )開發,但是 so 如何和應用程式一起打包成 apk 併發布?這裡面也存在技術障礙.我曾經花了不少時間,安裝交叉編譯器建立 so ,並通過 asset (資源)方式,實現捆綁 so 釋出.但這種方式只能屬於取巧的方式,並非官方支援.所以,在 NDK 出來之前,我們將 “Java+C” 的開發模式稱之為灰色模式,即官方既不宣告 “ 支援這種方式 ” ,也不宣告 “ 不支援這種方式 ” .

誤解二:有了 NDK ,我們可以使用純 C 開發 Android 應用 
 Android SDK採用 Java 語言釋出,把眾多的 C 開發人員排除在第三方應用開發外( 注意:我們所有討論都是基於“ 第三方應用開發 ” , Android 系統基於 Linux ,系統級別的開發肯定是支援 C 語言的. ).NDK 的釋出,許多人會誤以為,類似於 Symbian . WM ,在 Android 平臺上終於可以使用純 C . C++ 開發第三方應用了!其實不然, NDK 文件明確說明: it is not a good way .因為 NDK 並沒有提供各種系統事件處理支援,也沒有提供應用程式生命週期維護.此外,在本次釋出的 NDK 中,應用程式 UI 方面的 API 也沒有提供.至少目前來說,使用純 C . C++ 開發一個完整應用的條件還不完備.
   1.NDK 是一系列工具的集合.

NDK提供了一系列的工具,幫助開發者快速開發 C (或 C++ )的動態庫,並能自動將 so 和 java 應用一起打包成 apk .這些工具對開發者的幫助是巨大的. 
NDK集成了交叉編譯器,並提供了相應的 mk 檔案隔離 CPU .平臺. ABI 等差異,開發人員只需要簡單修改 mk 檔案(指出 “ 哪些檔案需要編譯 ” . “ 編譯特性要求 ” 等),就可以創建出 NDK可以自動地將 so 和 Java 應用一起打包,極大地減輕了開發人員的打包工作. 
   2.NDK 提供了一份穩定.功能有限的 API 標頭檔案宣告.

 Google明確宣告該 API 是穩定的,在後續所有版本中都穩定支援當前釋出的 API .從該版本的 NDK 中看出,這些 API 支援的功能非常有限,包含有: C 標準庫( libc ).標準數學庫( libm ).壓縮庫( libz ). Log 庫( liblog ).

3.NDK 帶來什麼 
1.NDK 的釋出,使 “Java+C” 的開發方式終於轉正,成為官方支援的開發方式.

使用NDK ,我們可以將要求高效能的應用邏輯使用 C 開發,從而提高應用程式的執行效率. 
使用NDK ,我們可以將需要保密的應用邏輯使用 C 開發.畢竟, Java 包都是可以反編譯的. 
NDK促使專業 so 元件商的出現.(樂觀猜想,要視乎 Android 使用者的數量) 
    2.NDK 將是 Android 平臺支援 C 開發的開端. NDK提供了的開發工具集合,使開發人員可以便捷地開發.釋出 C 元件.同時, Google承諾在 NDK 後續版本中提高 “ 可調式 ” 能力,即提供遠端的 gdb 工具,使我們可以便捷地除錯 C 原始碼.在支援 Android 平臺 C 開發,我們能感覺到 Google 花費了很大精力,我們有理由憧憬 “C 元件支援 ” 只是 Google Android 平臺上C 開發的開端.畢竟, C 程式設計師仍然是碼農陣營中的絕對主力,將這部分人排除在 Android 應用開發之外,顯然是不利於 Android 平臺繁榮昌盛的.