Android面試題

zygang1988發表於2012-06-27

自己總結的最強android應用面試題集
1.activity的生命週期。

方法

描述

可被殺死

下一個

onCreate()

activity第一次被建立的時候呼叫。這裡是你做所有初始化設定的地方──建立檢視、繫結資料至列表等。如果曾經有狀態記錄(參閱後述Saving Activity State。),則呼叫此方法時會傳入一個包含著此activity以前狀態的包物件做為引數。 

總繼之以onStart()。

onStart()

    

onRestart()

activity停止後,在再次啟動之前被呼叫。 

總繼之以onStart()。

onStart()

onStart()

activity正要變得為使用者所見時被呼叫。 

activity轉向前臺時繼以onResume(),在activity變為隱藏時繼以onStop()。

onResume() 
or
onStop()

    

onResume()

activity開始與使用者進行互動之前被呼叫。此時activity位於堆疊頂部,並接受使用者輸入。 

繼之以onPause()。

onPause()

onPause()

當系統將要啟動另一個activity時呼叫。此方法主要用來將未儲存的變化進行持久化,停止類似動畫這樣耗費CPU的動作等。這一切動作應該在短時間內完成,因為下一個activity必須等到此方法返回後才會繼續。 

activity重新回到前臺是繼以onResume()。當activity變為使用者不可見時繼以onStop()。

onResume() 
or
onStop()

onStop()

activity不再為使用者可見時呼叫此方法。這可能發生在它被銷燬或者另一個activity(可能是現存的或者是新的)回到執行狀態並覆蓋了它。 

如果activity再次回到前臺跟使用者互動則繼以onRestart(),如果關閉activity則繼以onDestroy()。

onRestart() 
or
onDestroy()

onDestroy()

activity銷燬前呼叫。這是activity接收的最後一個呼叫。這可能發生在activity結束(呼叫了它的 finish() 方法)或者因為系統需要空間所以臨時的銷燬了此acitivity的例項時。你可以用isFinishing() 方法來區分這兩種情況。

nothing

2.橫豎屏切換時候activity的生命週期

1.不設定Activityandroid:configChanges,切屏會重新呼叫各個生命週期,切橫屏時會執行一次,切豎屏時會執行兩次

2.設定Activityandroid:configChanges="orientation",切屏還是會重新呼叫各個生命週期,切橫、豎屏時只會執行一次

3.設定Activityandroid:configChanges="orientation|keyboardHidden",切屏不會重新呼叫各個生命週期,只會執行onConfigurationChanged方法.

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

   兩種,一種是Tween動畫、還有一種是Frame動畫。Tween動畫,這種實現方式可以使檢視元件移動、放大、縮小以及產生透明度的變化;另一種Frame動畫,傳統的動畫方法,通過順序的播放排列好的圖片來實現,類似電影。

4. 一條最長的簡訊息約佔多少byte?

   中文70(包括標點),英文160個位元組。

5.handler機制的原理

  andriod提供了 Handler 和 Looper 來滿足執行緒間的通訊。Handler 先進先出原則。Looper類用來管理特定執行緒內物件之間的訊息交換(Message Exchange)

  1)Looper: 一個執行緒可以產生一個Looper物件,由它來管理此執行緒裡的Message Queue(訊息佇列)

 2)Handler: 你可以構造Handler物件來與Looper溝通,以便push新訊息到Message Queue;或者接收LooperMessage Queue取出)所送來的訊息。

  3) Message Queue(訊息佇列):用來存放執行緒放入的訊息。

  4)執行緒:UI thread 通常就是main thread,而Android啟動程式時會替它建立一個Message Queue

 

6.什麼是嵌入式實時作業系統, Android 作業系統屬於實時作業系統嗎?

 

  嵌入式實時作業系統是指當外界事件或資料產生時,能夠接受並以足夠快的速度予以處理,其處理的結果又能在規定的時間之內來控制生產過程或對處理系統作出快速響應,並控制所有實時任務協調一致執行的嵌入式作業系統。主要用於工業控制、 軍事裝置、 航空航天等領域對系統的響應時間有苛刻的要求,這就需要使用實時系統。又可分為軟實時和硬實時兩種,而android是基於linux核心的,因此屬於軟實時。

7.android中執行緒與執行緒,程式與程式之間如何通訊

1、一個 Android 程式開始執行時,會單獨啟動一個Process
   預設情況下,所有這個程式中的Activity或者Service都會跑在這個Process
   預設情況下,一個Android程式也只有一個Process,但一個Process下卻可以有許多個Thread
2、一個 Android 程式開始執行時,就有一個主執行緒Main Thread被建立。該執行緒主要負責UI介面的顯示、更新和控制元件互動,所以又叫UI Thread
   一個Android程式建立之初,一個Process呈現的是單執行緒模型--Main Thread,所有的任務都在一個執行緒中執行。所以,Main Thread所呼叫的每一個函式,其耗時應該越短越好。而對於比較費時的工作,應該設法交給子執行緒去做,以避免阻塞主執行緒(主執行緒被阻塞,會導致程式假死 現象)。 

3Android單執行緒模型:Android UI操作並不是執行緒安全的並且這些操作必須在UI執行緒中執行。如果在子執行緒中直接修改UI,會導致異常。

8.Android dvm的程式和Linux的程式, 應用程式的程式是否為同一個概念 

  DVM指dalivk的虛擬機器。每一個Android應用程式都在它自己的程式中執行,都擁有一個獨立的Dalvik虛擬機器例項。而每一個DVM都是在Linux 中的一個程式,所以說可以認為是同一個概念。 

9.sim卡的EF 檔案有何作用 

  sim卡的檔案系統有自己規範,主要是為了和手機通訊,sim本 身可以有自己的作業系統,EF就是作儲存並和手機通訊用的 

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

  兩種,一種是Tween動畫、還有一種是Frame動畫。Tween動畫,這種實現方式可以使檢視元件移動、放大、縮小以及產生透明度的變化;另一種Frame動畫,傳統的動畫方法,通過順序的播放排列好的圖片來實現,類似電影。 

11.Activity變成一個視窗:Activity屬性設定 

  講點輕鬆的吧,可能有人希望做出來的應用程式是一個漂浮在手機主介面的東西,那麼很 簡單你只需要設定 一下Activity的主題就可以了在AndroidManifest.xml 中定義 Activity的 地方一句話: 

  Xml程式碼 

  1. android :theme="@android:style/Theme.Dialog" 

  這就使你的應用程式變成對話方塊的形式彈出來了,或者 

  Xml程式碼 

  1. android:theme="@android:style/Theme.Translucent" 

  就變成半透明的,[友情提示-.-]類似的這種activity的屬性可以在android.R.styleable 類的AndroidManifestActivity 方法中看到,AndroidManifest.xml中所有元素的屬性的介紹都可以參考這個類android.R.styleable 

  上面說的是屬性名稱,具體有什麼值是在android.R.style中 可以看到,比如這個"@android:style/Theme.Dialog" 就對應於android.R.style.Theme_Dialog ,('_'換成'.' < --注意:這個是文章內容不是笑臉)就可以用在描述檔案 中了,找找類定義和描述檔案中的對應關係就都明白了。 

12.如何將SQLite資料庫(dictionary.db檔案)與apk檔案一起釋出? 

  解答:可以將dictionary.db檔案複製到Eclipse Android工程中的res aw目錄中。所有在res aw目錄中的檔案不會被壓縮,這樣可以直接提取該目錄中的檔案。可以將dictionary.db檔案複製到res aw目錄中 

13.如何將開啟res aw目錄中的資料庫檔案? 

  解答:在Android中不能直接開啟res aw目錄中的資料庫檔案,而需要在程式第一次啟動時將該檔案複製到手機記憶體或SD卡的某個目錄中,然後再開啟該資料庫檔案。複製的基本方法是使用getResources().openRawResource方法獲得res aw目錄中資源的 InputStream物件,然後將該InputStream物件中的資料寫入其他的目錄中相應檔案中。在Android SDK中可以使用SQLiteDatabase.openOrCreateDatabase方法來開啟任意目錄中的SQLite資料庫檔案。 

14.在androidmvc的具體體現

Android 的官方建議應用程式的開發採用MVC 模式。何謂MVC?先看看下圖

MVC Model,View,Controller 的縮寫,從上圖可以看出MVC 包含三個部分:

.. 模型(Model)物件:是應用程式的主體部分,所有的業務邏輯都應該寫在該

層。

.. 檢視(View)物件:是應用程式中負責生成使用者介面的部分。也是在整個

MVC 架構中使用者唯一可以看到的一層,接收使用者的輸入,顯示處理結果。

.. 控制器(Control)物件:是根據使用者的輸入,控制使用者介面資料顯示及更新

Model 物件狀態的部分,控制器更重要的一種導航功能,想用使用者出發的相

關事件,交給哦得了處理。

Android 鼓勵弱耦合和元件的重用,在Android MVC 的具體體現如下

1)檢視層(view:一般採用xml檔案進行介面的描述,使用的時候可以非常方便的引入,當然,如何你對android瞭解的比較的多了話,就一定可 以想到在android中也可以使用javascript+html等的方式作為view層,當然這裡需要進行javajavascript之間的通 信,幸運的是,android提供了它們之間非常方便的通訊實現。

  2)控制層(controller):android的控制層的重 任通常落在了眾多的acitvity的肩上,這句話也就暗含了不要在acitivity中寫程式碼,要通過activity交割model業務邏輯層處理, 這樣做的另外一個原因是android中的acitivity的響應時間是5s(這句話很重要),如果耗時的操作放在這裡,程式就很容易被回收掉。

  3)模型層(model):對資料庫的操作、對網路等的操作都應該在model裡面處理,當然對業務計算等操作也是必須放在的該層的。

15.Android系統的架構

android的系統架構和其作業系統一樣,採用了分層的架構。從架構圖看,android分為四個層,從高層到低層分別是應用程式層、應用程式框架層、系統執行庫層和linux核心層。

  1.應用程式

  Android會同一系列核心應用程式包一起釋出,該應用程式包包括email客戶端,SMS短訊息程式,日曆,地圖,瀏覽器,聯絡人管理程式等。所有的應用程式都是使用JAVA語言編寫的。

  2.應用程式框架

  開發人員也可以完全訪問核心應用程式所使用的API框架。該應用程式的架構設計簡化了元件的重用;任何一個應用程式都可以釋出它的功能塊並且任何其它的應用程式都可以使用其所釋出的功能塊(不過得遵循框架的安全性限制)。同樣,該應用程式重用機制也使使用者可以方便的替換程式元件。

  隱藏在每個應用後面的是一系列的服務和系統其中包括;

  豐富而又可擴充套件的檢視(Views),可以用來構建應用程式, 它包括列表(lists),網格(grids),文字框(text boxes),按鈕(buttons), 甚至可嵌入的web瀏覽器。

  內容提供器(Content Providers)使得應用程式可以訪問另一個應用程式的資料(如聯絡人資料庫), 或者共享它們自己的資料

  資源管理器(Resource Manager)提供 非程式碼資源的訪問,如本地字串,圖形,和佈局檔案( layout files )

  通知管理器 (Notification Manager) 使得應用程式可以在狀態列中顯示自定義的提示資訊。

  活動管理器( Activity Manager) 用來管理應用程式生命週期並提供常用的導航回退功能。

  有關更多的細節和怎樣從頭寫一個應用程式,請參考 如何編寫一個 Android 應用程式.

  3.系統執行庫

  1)程式庫

  Android 包含一些C/C++庫,這些庫能被Android系統中不同的元件使用。它們通過 Android 應用程式框架為開發者提供服務。以下是一些核心庫:

  系統 庫 一個從 BSD 繼承來的標準 系統函式庫( libc ), 它是專門為基於 embedded linux 的裝置定製的。

  媒體庫 基於 PacketVideo OpenCORE;該庫支援多種常用的音訊、視訊格式回放和錄製,同時支援靜態影象檔案。編碼格式包括MPEG4, H.264, MP3, AAC, AMR, JPG, PNG 

  * Surface Manager - 對顯示子系統的管理,並且為多個應用程式提 供了2D3D圖層的無縫融合。

  * LibWebCore - 一個最新的web瀏覽器引擎用,支援Android瀏覽器和一個可嵌入的web檢視。

  * SGL - 底層的2D圖形引擎

  * 3D libraries - 基於OpenGL ES 1.0 APIs實現;該庫可以使用硬體 3D加速(如果可用)或者使用高度優化的3D軟加速。

  * FreeType -點陣圖(bitmap)和向量(vector)字型顯示。

  * SQLite - 一個對於所有應用程式可用,功能強勁的輕型關係型資料庫引擎。

  2)Android 執行庫

  Android 包括了一個核心庫,該核心庫提供了JAVA程式語言核心庫的大多數功能。

  每一個Android應用程式都在它自己的程式中執行,都擁有一個獨立的Dalvik虛擬機器例項。Dalvik被設計成一個裝置可以同時高效地執行多個虛擬系統。 Dalvik虛擬機器執行(.dex)Dalvik可執行檔案,該格式檔案針對小記憶體使用做了優化。同時虛擬機器是基於暫存器的,所有的類都經由JAVA編譯器編譯,然後通過SDK中 的 “dx” 工具轉化成.dex格式由虛擬機器執行。

  Dalvik虛擬機器依賴於linux核心的一些功能,比如執行緒機制和底層記憶體管理機制。

  4.Linux 核心

Android 的核心繫統服務依賴於 Linux 2.6 核心,如安全性,記憶體管理,程式管理, 網路協議棧和驅動模型。 Linux 核心也同時作為硬體和軟體棧之間的抽象層。

16.Android常用控制元件的資訊

單選框(RadioButtonRadioGroup)

RadioGroup用於對單選框進行分組,相同組內的單選框只有一個單選框被選中。

事件:setOnCheckedChangeListener(),處理單選框被選擇事件。把RadioGroup.OnCheckedChangeListener例項作為引數傳入。

多選框(CheckBox):

每個多選框都是獨立的,可以通過迭代所有的多選框,然後根據其狀態是否被選中在獲取其值。

事件:setOnCheckChangeListener()處理多選框被選擇事件。把CompoundButton.OnCheckedChangeListener例項作為引數傳入

下拉選單框(Spring)

Spinner.getItemAtPosition(Spinner.getSelectedItemPosition());獲取下拉選單框的值。

事件:setOnItemSelectedListener(),處理下拉選單框被選擇事件把AdapterView.OnItemSelectedListener例項作為引數傳入;

拖動條(SeekBar)

SeekBar.getProgress()獲取拖動條當前值

事件:setOnSeekBarChangeListener(),處理拖動條值變化事件,把SeekBar.OnSeekBarChangeListener例項作為引數傳入。

選單(Menu):

重寫ActivityonCreatOptionMenu(Menu menu)方法,該方法用於建立選項選單,咋使用者按下手機的"Menu"按鈕時就會顯示建立好的選單,在onCreatOptionMenu(Menu Menu)方法內部可以呼叫Menu.add()方法實現選單的新增。

重寫ActivityonMenuItemSelected()方法,該方法用於處理選單被選擇事件。

進度對話方塊(ProgressDialog)

建立並顯示一個進度對話方塊:ProgressDialog.show(ProgressDialogActivity.this,"請稍等""資料正在載入中...."true)

設定對話方塊的風格:setProgressStyle()

ProgressDialog.STYLE_SPINNER  旋轉進度條風格(為預設風格)

ProgressDialog.STYLE_HORIZONTAL 橫向進度條風格

17.請介紹下Android中常用的五種佈局

Android佈局是應用介面開發的重要一環,在Android中,共有五種佈局方式,分別是:FrameLayout(框架佈局),LinearLayout (線性佈局),

AbsoluteLayout(絕對佈局),RelativeLayout(相對佈局),TableLayout(表格佈局)。 

  1.FrameLayout    

    這個佈局可以看成是牆腳堆東西,有一個四方的矩形的左上角牆腳,我們放了第一個東西,要再放一個,那就在放在原來放的位置的上面,這樣依次的放,會蓋住原來的東西。這個佈局比較簡單,也只能放一點比較簡單的東西。    

2.LinearLayout    

線性佈局,這個東西,從外框上可以理解為一個div,他首先是一個一個從上往下羅列在螢幕上。每一個LinearLayout裡面又可分為垂直佈局 (android:orientation="vertical")和水平佈局(android:orientation="horizontal" )。當垂直佈局時,每一行就只有一個元素,多個元素依次垂直往下;水平佈局時,只有一行,每一個元素依次向右排列。    

linearLayout中有一個重要的屬性 android:layout_weight="1",這個weight在垂直佈局時,代表行距;水平的時候代表列寬;weight值越大就越大。    

3.AbsoluteLayout    

    絕對佈局猶如div指定了absolute屬性,用X,Y座標來指定元素的位置android:layout_x="20px" android:layout_y="12px" 這種佈局方式也比較簡單,但是在垂直隨便切換時,往往會出問題,而且多個元素的時候,計算比較麻煩。    

4.RelativeLayout    

    相對佈局可以理解為某一個元素為參照物,來定位的佈局方式。主要屬性有:    

    相對於某一個元素    

    android:layout_below="@id/aaa" 該元素在 idaaa的下面    

    android:layout_toLeftOf="@id/bbb" 改元素的左邊是bbb    

     相對於父元素的地方    

     android:layout_alignParentLeft="true"  在父元素左對齊    

     android:layout_alignParentRight="true" 在父元素右對齊    

     還可以指定邊距等,具體詳見API    

            

5.TableLayout    

     表格佈局類似Html裡面的Table。每一個TableLayout裡面有表格行TableRowTableRow裡面可以具體定義每一個元素,設定他的對齊方式 android:gravity="" 。    

     每一個佈局都有自己適合的方式,另外,這五個佈局元素可以相互巢狀應用,做出美觀的介面。

18.如何啟用Service,如何停用Service 

Android中的服務和windows中的服務是類似的東西,服務一般沒有使用者操作介面,它執行於系統中不容易被使用者發覺,可以使用它開發如監控之類的程式。服務的開發比較簡單,如下:

第一步:繼承Service

public class SMSService extends Service {

}

第二步:在AndroidManifest.xml檔案中的<application>節點裡對服務進行配置:

<service android:name=".SMSService" />

 

服務不能自己執行,需要通過呼叫Context.startService()Context.bindService()方法啟動服務。這兩個方法都可以啟動Service,但是它們的使用場合有所不同。使用startService()方法啟用服務,呼叫者與服務之間沒有關連,即使呼叫者退出了,服務仍然執行。使用bindService()方法啟用服務,呼叫者與服務繫結在了一起,呼叫者一旦退出,服務也就終止,大有“不求同時生,必須同時死”的特點。

 

如果打算採用Context.startService()方法啟動服務,在服務未被建立時,系統會先呼叫服務的onCreate()方法,接著呼叫onStart()方法。如果呼叫startService()方法前服務已經被建立,多次呼叫startService()方法並不會導致多次建立服務,但會導致多次呼叫onStart()方法。採用startService()方法啟動的服務,只能呼叫Context.stopService()方法結束服務,服務結束時會呼叫onDestroy()方法。

 

如果打算採用Context.bindService()方法啟動服務,在服務未被建立時,系統會先呼叫服務的onCreate()方法,接著呼叫onBind()方法。這個時候呼叫者和服務繫結在一起,呼叫者退出了,系統就會先呼叫服務的onUnbind()方法,接著呼叫onDestroy()方法。如果呼叫bindService()方法前服務已經被繫結,多次呼叫bindService()方法並不會導致多次建立服務及繫結(也就是說onCreate()onBind()方法並不會被多次呼叫)。如果呼叫者希望與正在繫結的服務解除繫結,可以呼叫unbindService()方法,呼叫該方法也會導致系統呼叫服務的onUnbind()-->onDestroy()方法。

服務常用生命週期回撥方法如下:

onCreate() 該方法在服務被建立時呼叫,該方法只會被呼叫一次,無論呼叫多少次startService()bindService()方法,服務也只被建立一次。

onDestroy()該方法在服務被終止時呼叫。

 

與採用Context.startService()方法啟動服務有關的生命週期方法

onStart() 只有採用Context.startService()方法啟動服務時才會回撥該方法。該方法在服務開始執行時被呼叫。多次呼叫startService()方法儘管不會多次建立服務,但onStart() 方法會被多次呼叫。

 

與採用Context.bindService()方法啟動服務有關的生命週期方法

onBind()只有採用Context.bindService()方法啟動服務時才會回撥該方法。該方法在呼叫者與服務繫結時被呼叫,當呼叫者與服務已經繫結,多次呼叫Context.bindService()方法並不會導致該方法被多次呼叫。

onUnbind()只有採用Context.bindService()方法啟動服務時才會回撥該方法。該方法在呼叫者與服務解除繫結時被呼叫

  1. 採用Context. bindService()方法啟動服務的程式碼如下:  
  2. public class HelloActivity extends Activity {  
  3.      ServiceConnection conn = new ServiceConnection() {  
  4.               public void onServiceConnected(ComponentName name, IBinder service) {  
  5.            }  
  6.            public void onServiceDisconnected(ComponentName name) {  
  7.            }  
  8.      };  
  9.     @Override   
  10. public void onCreate(Bundle savedInstanceState) {   
  11.         Button button =(Button) this.findViewById(R.id.button);  
  12.         button.setOnClickListener(new View.OnClickListener(){  
  13.                public void onClick(View v) {  
  14.                   Intent intent = new Intent(HelloActivity.this, SMSService.class);  
  15.                   bindService(intent, conn, Context.BIND_AUTO_CREATE);  
  16.                   //unbindService(conn);//解除繫結   
  17.           }});         
  18.     }  
  19. }  


19.ListView優化

工作原理:

ListView 針對List中每個item,要求 adapter “給我一個檢視” (getView)

一個新的檢視被返回並顯示

如果我們有上億個專案要顯示怎麼辦?為每個專案建立一個新檢視?NO!這不可能!

實際上Android為你快取了檢視。

Android中有個叫做Recycler的構件,下圖是他的工作原理:

如果你有10億個專案(item),其中只有可見的專案存在記憶體中,其他的在Recycler中。

1. ListView先請求一個type1檢視(getView)然後請求其他可見的專案。convertViewgetView中是空(null)

2. item1滾出螢幕,並且一個新的專案從螢幕低端上來時,ListView再請求一個type1檢視。convertView此時不是空值了,它的值是item1。你只需設定新的資料然後返回convertView,不必重新建立一個檢視。

20廣播接收者生命週期

一個廣播接收者有一個回撥方法:void onReceive(Context curContext, Intent broadcastMsg)。當一個廣播訊息到達接收者是,Android呼叫它的onReceive()方法並傳遞給它包含訊息的Intent物件。廣播接收者被認為僅當它執行這個方法時是活躍的。當onReceive()返回後,它是不活躍的。

有一個活躍的廣播接收者的程式是受保護的,不會被殺死。但是系統可以在任何時候殺死僅有不活躍元件的程式,當佔用的記憶體別的程式需要時。

這帶來一個問題,當一個廣播訊息的響應時費時的,因此應該在獨立的執行緒中做這些事,遠離使用者介面其它元件執行的主執行緒。如果onReceive()衍生執行緒然後返回,整個程式,包括新的執行緒,被判定為不活躍的(除非程式中的其它應用程式元件是活躍的),將使它處於被殺的危機。解決這個問題的方法是onReceive()啟動一個服務,及時服務做這個工作,因此係統知道程式中有活躍的工作在做。

21.設計模式和IoC(控制反轉)

Android 框架魅力的源泉在於IoC,在開發Android 的過程中你會時刻感受到IoC 帶來

的巨大方便,就拿Activity 來說,下面的函式是框架呼叫自動呼叫的:

protected void onCreate(Bundle savedInstanceState) 

不是程式編寫者主動去呼叫,反而是使用者寫的程式碼被框架呼叫,這也就反轉

了!當然IoC 本身的內涵遠遠不止這些,但是從這個例子中也可以窺視出IoC

帶來的巨大好處。此類的例子在Android 隨處可見,例如說資料庫的管理類,

例如說Android SAX Handler 的呼叫等。有時候,您甚至需要自己編寫簡

單的IoC 實現,上面展示的多執行緒現在就是一個說明。

22.Android中的長度單位詳解

現在這裡介紹一下dp spdp 也就是dip。這個和sp 基本類似。如果設定表示長度、高度等屬性時可以使用dp sp。但如果設定字型,需要使用spdp 是與密度無關,sp 除了與密度無關外,還與scale 無關。如果螢幕密度為160,這時dp sp px 是一樣的。1dp=1sp=1px,但如果使用px 作單位,如果螢幕大小不變(假設還是3.2 寸),而螢幕密度變成了320。那麼原來TextView 的寬度設成160px,在密度為320 3.2 寸螢幕裡看要比在密度為160 3.2 寸螢幕上看短了一半。但如果設定成160dp 160sp 的話。系統會自動將width 屬性值設定成320px 的。也就是160 * 320 / 160。其中320 / 160 可稱為密

度比例因子。也就是說,如果使用dp sp,系統會根據螢幕密度的變化自動

進行轉換。

下面看一下其他單位的含義

px:表示螢幕實際的象素。例如,320*480 的螢幕在橫向有320個象素,

在縱向有480 個象素。

in:表示英寸,是螢幕的物理尺寸。每英寸等於2.54 釐米。例如,形容

手機螢幕大小,經常說,3.2(英)寸、3.5(英)寸、4(英)寸就是指這個

單位。這些尺寸是螢幕的對角線長度。如果手機的螢幕是3.2 英寸,表示手機

的螢幕(可視區域)對角線長度是3.2*2.54 = 8.128 釐米。讀者可以去量

一量自己的手機螢幕,看和實際的尺寸是否一致。                      

23. 4activity的啟動模式

standard: 標準模式,一呼叫startActivity()方法就會產生一個新的例項。 

singleTop: 如果已經有一個例項位於Activity棧的頂部時,就不產生新的例項,而只是呼叫Activity中的newInstance()方法。如果不位於棧頂,會產生一個新的例項。 

singleTask: 會在一個新的task中產生這個例項,以後每次呼叫都會使用這個,不會去產生新的例項了。 

singleInstance: 這個跟singleTask基本上是一樣,只有一個區別:在這個模式下的Activity例項所處的task中,只能有這個activity例項,不能有其他的例項。 

24.什麼是ANR 如何避免它?

ANRApplication Not Responding,五秒 

Android中,活動管理器和視窗管理器這兩個系統服務負責監視應用程式的響應。當出現下列情況時,Android就會顯示ANR對話方塊了: 

  對輸入事件(如按鍵、觸控式螢幕事件)的響應超過5秒 

  意向接受器(intentReceiver)超過10秒鐘仍未執行完畢 

  Android應用程式完全執行在一個獨立的執行緒中(例如main)。這就意味著,任何在主執行緒中執行的,需要消耗大量時間的操作都會引發ANR。因為此時,你的應用程式已經沒有機會去響應輸入事件和意向廣播(Intent broadcast)。 

  因此,任何執行在主執行緒中的方法,都要儘可能的只做少量的工作。特別是活動生命週期中的重要方法如onCreate()和 onResume()等更應如此。潛在的比較耗時的操作,如訪問網路和資料庫;或者是開銷很大的計算,比如改變點陣圖的大小,需要在一個單獨的子執行緒中完成(或者是使用非同步請求,如資料庫操作)。但這並不意味著你的主執行緒需要進入阻塞狀態已等待子執行緒結束 -- 也不需要呼叫Therad.wait()或者Thread.sleep()方法。取而代之的是,主執行緒為子執行緒提供一個控制程式碼(Handler),讓子執行緒在即將結束的時候呼叫它(xing:可以參看Snake的例子,這種方法與以前我們所接觸的有所不同),還有一種方法就是利用服務來完成。使用這種方法涉及你的應用程式,能夠保證你的程式對輸入保持良好的響應,從而避免因為輸入事件超過5秒鐘不被處理而產生的ANR。這種實踐需要應用到所有顯示使用者介面的執行緒,因為他們都面臨著同樣的超時問題。 

25.Android Intent的使用

在一個Android應用中,主要是由一些元件組成,(Activity,Service,ContentProvider,etc.)在這些元件之間的通訊中,由Intent協助完成。

正如網上一些人解析所說,Intent負責對應用中一次操作的動作、動作涉及資料、附加資料進行描述,Android則根據此Intent的描述,負責找到對應的元件,將 Intent傳遞給呼叫的元件,並完成元件的呼叫。Intent在這裡起著實現呼叫者與被呼叫者之間的解耦作用。
Intent傳遞過程中,要找到目標消費者(另一個Activity,IntentReceiver或Service),也就是Intent的響應者,有兩種方法來匹配:
1,顯示匹配(Explicit): 

  1. public TestB extents Activity  
  2. {  
  3.  .........  
  4. };  
  5.  public class Test extends Activity  
  6. {  
  7.      ......  
  8.      public void switchActivity()  
  9.      {  
  10.             Intent i = new Intent(Test.this, TestB.class);  
  11.             this.startActivity(i);  
  12.      }  
  13. }  



程式碼簡潔明瞭,執行了switchActivity()函式,就會馬上跳轉到名為TestB的Activity中。 

2,隱式匹配(Implicit):
   
  隱式匹配,首先要匹配Intent的幾項值:Action, Category, Data/Type,Component
如果填寫了Componet就是上例中的Test.class)這就形成了顯示匹配。所以此部分只講前幾種匹配。匹配規則為最大匹配規則,

1,如果你填寫了Action,如果有一個程式的Manifest.xml中的某一個Activity的IntentFilter段中定義了包含了相同的Action那麼這個Intent就與這個目標Action匹配,如果這個Filter段中沒有定義Type,Category,那麼這個Activity就匹配了。但是如果手機中有兩個以上的程式匹配,那麼就會彈出一個對話可框來提示說明。
Action的值在Android中有很多預定義,如果你想直接轉到你自己定義的Intent接收者,你可以在接收者的IntentFilter中加入一個自定義的Action值(同時要設定Category值為"android.intent.category.DEFAULT"),在你的Intent中設定該值為Intent的Action,就直接能跳轉到你自己的Intent接收者中。因為這個Action在系統中是唯一的。
2,data/type,你可以用Uri來做為data,比如Uri uri = Uri.parse(http://www.google.com );
Intent i = new Intent(Intent.ACTION_VIEW,uri);手機的Intent分發過程中,會根據http://www.google.com 的scheme判斷出資料型別type
手機的Brower則能匹配它,在Brower的Manifest.xml中的IntenFilter中首先有ACTION_VIEW Action,也能處理http:的type,

3,至於分類Category,一般不要去在Intent中設定它,如果你寫Intent的接收者,就在Manifest.xml的Activity的IntentFilter中包含android.category.DEFAULT,這樣所有不設定Category(Intent.addCategory(String c);)的Intent都會與這個Category匹配。

4,extras(附加資訊),是其它所有附加資訊的集合。使用extras可以為元件提供擴充套件資訊,比如,如果要執行“傳送電子郵件”這個動作,可以將電子郵件的標題、正文等儲存在extras裡,傳給電子郵件傳送元件。

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的右側。

  1. <LinearLayout   
  2.     xmlns:android="http://schemas.android.com/apk/res/android"   
  3.     android:orientation="vertical"   
  4.     android:layout_width="fill_parent"   
  5.     android:layout_height="fill_parent">   
  6.     <EditText   
  7.         android:layout_width="wrap_content"   
  8.         android:gravity="center"   
  9.         android:layout_height="wrap_content"   
  10.         android:text="one"   
  11.         android:layout_gravity="right"/>   
  12. </LinearLayout>  




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

37.paddingmargin的區別

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

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

view plaincopy to clipboardprint?

  1. <?xml version="1.0" encoding="utf-8"?>    
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    
  3.     android:orientation="vertical"    
  4.     android:layout_width="fill_parent"    
  5.     android:layout_height="fill_parent"    
  6.     android:paddingLeft="10dip"    
  7.     android:paddingRight="10dip"    
  8.     android:paddingTop="10dip"    
  9.     android:paddingBottom="10dip"    
  10.     >    
  11. <TextView      
  12.     android:layout_width="wrap_content"     
  13.     android:layout_height="wrap_content"     
  14.     android:background="#FF0000"    
  15.     android:text="@string/hello"    
  16.     android:paddingLeft="50dip"    
  17.     android:paddingRight="50dip"    
  18.     android:paddingTop="50dip"    
  19.     android:paddingBottom="50dip"    
  20.     android:layout_marginBottom="10dip"    
  21.     />    
  22.     <TextView      
  23.     android:layout_width="wrap_content"     
  24.     android:layout_height="wrap_content"     
  25.     android:background="#FF0000"    
  26.     android:text="@string/hello"    
  27.     android:paddingLeft="50dip"    
  28.     android:paddingRight="50dip"    
  29.     android:paddingTop="50dip"    
  30.     android:paddingBottom="50dip"    
  31.     android:layout_marginBottom="10dip"    
  32.     />    
  33.     <TextView      
  34.     android:layout_width="wrap_content"     
  35.     android:layout_height="wrap_content"     
  36.     android:background="#FF0000"    
  37.     android:text="@string/hello"    
  38.     android:paddingLeft="50dip"    
  39.     android:paddingRight="50dip"    
  40.     android:paddingTop="50dip"    
  41.     android:paddingBottom="50dip"    
  42.     android:layout_marginBottom="10dip"    
  43.     />    
  44.     <TextView      
  45.     android:layout_width="wrap_content"     
  46.     android:layout_height="wrap_content"     
  47.     android:background="#FF0000"    
  48.     android:text="@string/hello"    
  49.     android:paddingLeft="50dip"    
  50.     android:paddingRight="50dip"    
  51.     android:paddingTop="50dip"    
  52.     android:paddingBottom="50dip"    
  53.     android:layout_marginBottom="10dip"    
  54.     />    
  55. </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 平臺繁榮昌盛的.

 

相關文章