Android面試題

手頭上的項目要交接完了,該找工作了,得複習複習一些面試題了。所以就到掘金知乎 去找面試題看了,mark下來,以後不迷路-_-

  • Android的四大組件是哪些,它們的作用?

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

    service:後臺服務於Activity,封裝有一個完整的功能邏輯實現,接受上層指令,完成相關的事物,定義好需要接受的Intent提供同步和異步的接口

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

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

  • 請介紹下Android中常用的五種佈局。

    常用五種佈局方式,分別是:FrameLayout(框架佈局),LinearLayout (線性佈局),AbsoluteLayout(絕對佈局),RelativeLayout(相對佈局),TableLayout(表格佈局)。2016 google I/O大會上加了ConstraintLayout,AndroidStudio2.3以後默認的佈局就是ConstraintLayout。

    一、FrameLayout:所有東西依次都放在左上角,會重疊,這個佈局比較簡單,也只能放一點比較簡單的東西。
    三、AbsoluteLayout:絕對佈局用X,Y座標來指定元素的位置,比較少用。
    四、RelativeLayout:相對佈局可以理解爲某一個元素爲參照物,來定位的佈局方式。
    五、TableLayout:表格佈局,每一個TableLayout裏面有表格行TableRow,TableRow裏面可以具體定義每一個元素。

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

    答:兩種,一種是Tween動畫、還有一種是Frame動畫。Tween動畫,這種實現方式可以使視圖組件移動、放大、縮小以及產生透明度的變化;另一種Frame動畫,傳統的動畫方法,通過順序的播放排列好的圖片來實現,類似電影。還有一種,PropertyAnimation(屬性動畫):屬性動畫不再僅僅是一種視覺效果了,而是一種不斷地對值進行操作的機制,並將值賦到指定對象的指定屬性上,可以是任意對象的任意屬性。

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

    答:XML解析主要有三種方式,SAX、DOM、PULL。常規在PC上開發我們使用Dom相對輕鬆些,但一些性能敏感的數據庫或手機上還是主要採用SAX方式,SAX讀取是單向的,優點:不佔內存空間、解析屬性方便,但缺點就是對於套嵌多個分支來說處理不是很方便。而DOM方式會把整個XML文件加載到內存中去,這裏Android開發網提醒大家該方法在查找方面可以和XPath很好的結合如果數據量不是很大推薦使用,而PULL常常用在J2ME對於節點處理比較好,類似SAX方式,同樣很節省內存,在J2ME中我們經常使用的KXML庫來解析。

  • ListView的優化方案

    答:1、如果自定義適配器,那麼在getView方法中要考慮方法傳進來的參數contentView是否爲null,如果爲null就創建contentView並返回,如果不爲null則直接使用。在這個方法中儘可能少創建view。

    2、給contentView設置tag(setTag()),傳入一個viewHolder對象,用於緩存要顯示的數據,可以達到圖像數據異步加載的效果。

    3、如果listview需要顯示的item很多,就要考慮分頁加載。比如一共要顯示100條或者更多的時候,我們可以考慮先加載20條,等用戶拉到列表底部的時候再去加載接下來的20條。

  • 請介紹下Android的數據存儲方式

    答:五大數據存儲:SharedPreferences存儲、文件存儲、SQLite數據庫存儲、ContentProvider存儲、網絡存儲
    一:使用SharedPreferences存儲數據
    是Android提供的用來存儲一些簡單配置信息的一種機制,採用了XML格式將數據存儲到設備中。只能在同一個包內使用,不能在不同包之間使用。
    二:文件存儲數據
    文件存儲方式是一種較常用的方法,在Android中讀取/寫入文件的方法,與 Java中實現I/O的程序是完全一樣的,提供了openFileInput()和openFileOutput()方法來讀取設備上的文件。
    三:SQLite數據庫存儲
    SQLite是Android所帶的一個標準的數據庫,它支持SQL語句,是一個輕量級的嵌入式數據庫。
    四:ContentProvider存儲
    主要應用程序之間進行數據交換,從而能夠讓其他的應用保存或讀取此ContentProvider的各種數據類型。
    五:網絡存儲數據
    通過網絡上提供給我們的存儲空間來上傳(存儲)和下載(獲取)我們存儲在網絡空間中的數據信息。

  • activity的啓動模式有哪些?是什麼含義?

    答:在android裏,有4種activity的啓動模式,分別爲:
    “standard” (默認)
    “singleTop”
    “singleTask”
    “singleInstance”
    1、standard:Activity的默認加載方式,該方法會通過跳轉到一個新的Activity,同時將該實例壓入到棧中(不管該Activity是否已經存在在Task棧中,都是採用new操作,生命週期從onCreate()開始)。例如:棧中順序是A B C D,此時D通過Intent跳轉到A,那麼棧中結構就變成A B C D A,點擊返回按鈕的顯示順序是D C B A,依次摧毀。

    2、singleTop:singleTop模式下,當前Activity D位於棧頂的時候,如果通過Intent跳轉到它本身的Activity(D),那麼不會重新創建一個新的D實例(走onNewIntent()),所以棧中的結構依次爲A B C D,如果跳轉到B,那麼由於B不處於棧頂,所以會新建一個B實例並壓入到棧中,結構就變成了A B C D B。應用實例:三條推送,點進去都是一個Activity,這肯定用singletop

    3、singleTask:singleTask模式下,Task棧中只能有一個對應的Activity實例。例如:Task棧1中結構爲:A B C D。此時D通過Intent跳轉到B(走onNewIntent()),則棧的結構變成了:A,B。其中的C和D被棧彈出銷燬了,也就是說位於B之上的實例都被銷燬了。通常應用於首頁,首頁肯定在棧底部,也只能在棧底部。

    4、singleInstance:singleInstance模式下,會將打開的Activity壓入一個新的任務棧中。例如:Task棧1中結構爲:A B C,C通過Intent跳轉到了D(D的模式爲singleInstance),那麼則會新建一個Task,棧1中結構依舊爲A B C,棧2中結構爲D。此時屏幕顯示D,之後D通過Intent跳轉到D,棧2不會壓入新的D,所以兩個棧中的情況沒發生改變。如果D跳轉到了C,那麼就會根據C對應的launchMode在棧1中進行對應的操作,C如果爲standard,那麼D跳轉到C,棧1的結構爲A B C C ,此時點擊返回按鈕,還是在C,棧1的結構變爲A B C,而不會回到D。

    它們主要有如下不同:

    1. 如何決定所屬task
      “standard”和”singleTop”的activity的目標task,和收到的Intent的發送者在同一個task內,除非intent包括參數FLAG_ACTIVITY_NEW_TASK。

    如果提供了FLAG_ACTIVITY_NEW_TASK參數,會啓動到別的task裏。
    “singleTask”和”singleInstance”總是把activity作爲一個task的根元素,他們不會被啓動到一個其他task裏。

    1. 是否允許多個實例
      “standard”和”singleTop”可以被實例化多次,並且存在於不同的task中,且一個task可以包括一個activity的多個實例;
      “singleTask”和”singleInstance”則限制只生成一個實例,並且是task的根元素。 singleTop要求如果創建intent的時候棧頂已經有要創建的Activity的實例,則將intent發送給該實例,而不發送給新的實例。
    2. 是否允許其它activity存在於本task內
      “singleInstance”獨佔一個task,其它activity不能存在那個task裏;如果它啓動了一個新的activity,不管新的activity的launch mode 如何,新的activity都將會到別的task裏運行(如同加了FLAG_ACTIVITY_NEW_TASK參數)。
      而另外三種模式,則可以和其它activity共存。
    3. 是否每次都生成新實例
      “standard”對於沒一個啓動Intent都會生成一個activity的新實例;
      “singleTop”的activity如果在task的棧頂的話,則不生成新的該activity的實例,直接使用棧頂的實例,否則,生成該activity的實例。
      比如現在task棧元素爲A-B-C-D(D在棧頂),這時候給D發一個啓動intent,如果D是 “standard”的,則生成D的一個新實例,棧變爲A-B-C-D-D。

    如果D是singleTop的話,則不會生產D的新實例,棧狀態仍爲A-B-C-D
    如果這時候給B發Intent的話,不管B的launchmode是”standard” 還是 “singleTop” ,都會生成B的新實例,棧狀態變爲A-B-C-D-B。
    “singleInstance”是其所在棧的唯一activity,它會每次都被重用。
    “singleTask”如果在棧頂,則接受intent,否則,該intent會被丟棄,但是該task仍會回到前臺。
    當已經存在的activity實例處理新的intent時候,會調用onNewIntent()方法 如果收到intent生成一個activity實例,那麼用戶可以通過back鍵回到上一個狀態;如果是已經存在的一個activity來處理這個intent的話,用戶不能通過按back鍵返回到這之前的狀態。

  • Activity的生命週期

    答:activity的生命週期方法有:onCreate()、onStart()、onReStart()、onResume()、onPause()、onStop()、onDestory()。

  • activity在屏幕旋轉時的生命週期

    答:不設置Activity的android:configChanges時,切屏會重新調用各個生命週期,切橫屏時會執行一次,切豎屏時會執行兩次;
    設置Activity的android:configChanges=”orientation”時,切屏還是會重新調用各個生命週期,切橫、豎屏時只會執行一次;
    設置Activity的android:configChanges=”orientation|keyboardHidden”時,切屏不會重新調用各個生命週期,只會執行onConfigurationChanged方法

  • 如何啓用Service,如何停用Service

    服務的開發比較簡單,如下:
    第一步:繼承Service類
    public class SMSService extends Service {}
    第二步:在AndroidManifest.xml文件中的節點裏對服務進行配置:
    服務不能自己運行,需要通過調用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()方法啓動服務時纔會回調該方法。該方法在調用者與服務解除綁定時被調用

  • 註冊廣播有幾種方式,這些方式有何優缺點?請談談Android引入廣播機制的用意

    答:首先寫一個類要繼承BroadcastReceiver
    第一種:在清單文件中聲明,添加
    
    <receive android:name=".IncomingSMSReceiver " >
    <intent-filter>
       <action android:name="android.provider.Telephony.SMS_RECEIVED")
    <intent-filter>
    <receiver>
    第二種使用代碼進行註冊如:
    IntentFilter filter =  new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
    IncomingSMSReceiver receiver = new IncomgSMSReceiver();
    registerReceiver(receiver.filter);
    兩種註冊類型的區別是:
    1)第一種不是常駐型廣播,也就是說廣播跟隨程序的生命週期。
    2)第二種是常駐型,也就是說當應用程序關閉後,如果有信息廣播來,程序也會被系統調用自動運行。
  • 請解釋下在單線程模型中Message、Handler、Message Queue、Looper之間的關係

    答:簡單的說,Handler獲取當前線程中的looper對象,looper用來從存放Message的MessageQueue中取出Message,再有Handler進行Message的分發和處理.

    Message Queue(消息隊列):用來存放通過Handler發佈的消息,通常附屬於某一個創建它的線程,可以通過Looper.myQueue()得到當前線程的消息隊列

    Handler:可以發佈或者處理一個消息或者操作一個Runnable,通過Handler發佈消息,消息將只會發送到與它關聯的消息隊列,然也只能處理該消息隊列中的消息

    Looper:是Handler和消息隊列之間通訊橋樑,程序組件首先通過Handler把消息傳遞給Looper,Looper把消息放入隊列。Looper也把消息隊列裏的消息廣播給所有的

    Handler:Handler接受到消息後調用handleMessage進行處理

    Message:消息的類型,在Handler類中的handleMessage方法中得到單個的消息進行處理

    在單線程模型下,爲了線程通信問題,Android設計了一個Message Queue(消息隊列), 線程間可以通過該Message Queue並結合Handler和Looper組件進行信息交換。下面將對它們進行分別介紹:

    1. Message
      Message消息,理解爲線程間交流的信息,處理數據後臺線程需要更新UI,則發送Message內含一些數據給UI線程。
    2. Handler
      Handler處理者,是Message的主要處理者,負責Message的發送,Message內容的執行處理。後臺線程就是通過傳進來的 Handler對象引用來sendMessage(Message)。而使用Handler,需要implement 該類的 handleMessage(Message)方法,它是處理這些Message的操作內容,例如Update UI。通常需要子類化Handler來實現handleMessage方法。
    3. Message Queue
      Message Queue消息隊列,用來存放通過Handler發佈的消息,按照先進先出執行。
      每個message queue都會有一個對應的Handler。Handler會向message queue通過兩種方法發送消息:sendMessage或post。這兩種消息都會插在message queue隊尾並按先進先出執行。但通過這兩種方法發送的消息執行的方式略有不同:通過sendMessage發送的是一個message對象,會被 Handler的handleMessage()函數處理;而通過post方法發送的是一個runnable對象,則會自己執行。
    4. Looper
      Looper是每條線程裏的Message Queue的管家。Android沒有Global的Message Queue,而Android會自動替主線程(UI線程)建立Message Queue,但在子線程裏並沒有建立Message Queue。所以調用Looper.getMainLooper()得到的主線程的Looper不爲NULL,但調用Looper.myLooper() 得到當前線程的Looper就有可能爲NULL。對於子線程使用Looper,API Doc提供了正確的使用方法:這個Message機制的大概流程:
      1. 在Looper.loop()方法運行開始後,循環地按照接收順序取出Message Queue裏面的非NULL的Message。
      2. 一開始Message Queue裏面的Message都是NULL的。當Handler.sendMessage(Message)到Message Queue,該函數裏面設置了那個Message對象的target屬性是當前的Handler對象。隨後Looper取出了那個Message,則調用 該Message的target指向的Hander的dispatchMessage函數對Message進行處理。在dispatchMessage方法裏,如何處理Message則由用戶指定,三個判斷,優先級從高到低:
        1) Message裏面的Callback,一個實現了Runnable接口的對象,其中run函數做處理工作;
        2) Handler裏面的mCallback指向的一個實現了Callback接口的對象,由其handleMessage進行處理;
        3) 處理消息Handler對象對應的類繼承並實現了其中handleMessage函數,通過這個實現的handleMessage函數處理消息。
        由此可見,我們實現的handleMessage方法是優先級最低的!
      3. Handler處理完該Message (update UI) 後,Looper則設置該Message爲NULL,以便回收!
        在網上有很多文章講述主線程和其他子線程如何交互,傳送信息,最終誰來執行處理信息之類的,個人理解是最簡單的方法——判斷Handler對象裏面的Looper對象是屬於哪條線程的,則由該線程來執行!
      4. 當Handler對象的構造函數的參數爲空,則爲當前所在線程的Looper;
      5. Looper.getMainLooper()得到的是主線程的Looper對象,Looper.myLooper()得到的是當前線程的Looper對象。
  • 簡要解釋一下activity、 intent 、intent filter、service、Broadcase、BroadcaseReceiver

    答:一個activity呈現了一個用戶可以操作的可視化用戶界面;一個service不包含可見的用戶界面,而是在後臺運行,可以與一個activity綁定,通過綁定暴露出來接口並與其進行通信;一個broadcast receiver是一個接收廣播消息並做出迴應的component,broadcast receiver沒有界面;一個intent是一個Intent對象,它保存了消息的內容。對於activity和service來說,它指定了請求的操作名稱和待操作數據的URI,Intent對象可以顯式的指定一個目標component。如果這樣的話,android會找到這個component(基於manifest文件中的聲明)並激活它。但如果一個目標不是顯式指定的,android必須找到響應intent的最佳component。它是通過將Intent對象和目標的intent filter相比較來完成這一工作的;一個component的intent filter告訴android該component能處理的intent。intent filter也是在manifest文件中聲明的。

  • 說說mvc模式的原理,它在android中的運用,android的官方建議應用程序的開發採用mvc模式。何謂mvc?

    mvc是model,view,controller的縮寫,mvc包含三個部分:
      模型(model)對象:是應用程序的主體部分,所有的業務邏輯都應該寫在該層。
      視圖(view)對象:是應用程序中負責生成用戶界面的部分。也是在整個mvc架構中用戶唯一可以看到的一層,接收用戶的輸入,顯示處理結果。
      控制器(control)對象:是根據用戶的輸入,控制用戶界面數據顯示及更新model對象狀態的部分,控制器更重要的一種導航功能,響應用戶出發的相關事件,交給m層處理。
      android鼓勵弱耦合和組件的重用,在android中mvc的具體體現如下:
      1)視圖層(view):一般採用xml文件進行界面的描述,使用的時候可以非常方便的引入,當然,如果你對android瞭解的比較的多了話,就一定可以想到在android中也可以使用JavaScript+html等的方式作爲view層,當然這裏需要進行java和javascript之間的通信,幸運的是,android提供了它們之間非常方便的通信實現。
      2)控制層(controller):android的控制層的重任通常落在了衆多的acitvity的肩上,這句話也就暗含了不要在acitivity中寫代碼,要通過activity交割model業務邏輯層處理,這樣做的另外一個原因是android中的acitivity的響應時間是5s,如果耗時的操作放在這裏,程序就很容易被回收掉。
      3)模型層(model):對數據庫的操作、對網絡等的操作都應該在model裏面處理,當然對業務計算等操作也是必須放在的該層的。

  • 什麼是ANR 如何避免它?

    答:ANR:Application Not Responding。在Android中,活動管理器和窗口管理器這兩個系統服務負責監視應用程序的響應,當用戶操作的在5s內應用程序沒能做出反應,BroadcastReceiver在10秒內沒有執行完畢,就會出現應用程序無響應對話框,這既是ANR。

    避免方法:Activity應該在它的關鍵生命週期方法(如onCreate()和onResume())裏儘可能少的去做創建操作。潛在的耗時操作,例如網絡或數據庫操作,或者高耗時的計算如改變位圖尺寸,應該在子線程裏(或者異步方式)來完成。主線程應該爲子線程提供一個Handler,以便完成時能夠提交給主線程。

  • 什麼情況會導致Force Close ?如何避免?能否捕獲導致其的異常?

    答:程序出現異常,比如nullpointer。
    避免:編寫程序時邏輯連貫,思維縝密。能捕獲異常,在logcat中能看到異常信息

  • 描述一下android的系統架構

    android系統架構分從下往上爲linux 內核層、運行庫、應用程序框架層、和應用程序層。
    linuxkernel:負責硬件的驅動程序、網絡、電源、系統安全以及內存管理等功能。
    libraries和 android runtime:libraries:即c/c++函數庫部分,大多數都是開放源代碼的函數庫,例如webkit(引擎),該函數庫負責 android網頁瀏覽器的運行,例如標準的c函數庫libc、openssl、sqlite等,當然也包括支持遊戲開發2dsgl和 3dopengles,在多媒體方面有mediaframework框架來支持各種影音和圖形文件的播放與顯示,例如mpeg4、h.264、mp3、 aac、amr、jpg和png等衆多的多媒體文件格式。android的runtime負責解釋和執行生成的dalvik格式的字節碼。
     applicationframework(應用軟件架構),java應用程序開發人員主要是使用該層封裝好的api進行快速開發。
      applications:該層是java的應用程序層,android內置的googlemaps、e-mail、即時通信工具、瀏覽器、mp3播放器等處於該層,java開發人員開發的程序也處於該層,而且和內置的應用程序具有平等的位置,可以調用內置的應用程序,也可以替換內置的應用程序。
      上面的四個層次,下層爲上層服務,上層需要下層的支持,調用下層的服務,這種嚴格分層的方式帶來的極大的穩定性、靈活性和可擴展性,使得不同層的開發人員可以按照規範專心特定層的開發。
    android應用程序使用框架的api並在框架下運行,這就帶來了程序開發的高度一致性,另一方面也告訴我們,要想寫出優質高效的程序就必須對整個 applicationframework進行非常深入的理解。精通applicationframework,你就可以真正的理解android的設計和運行機制,也就更能夠駕馭整個應用層的開發。

  • 請介紹下ContentProvider是如何實現數據共享的

    一個程序可以通過實現一個Content provider的抽象接口將自己的數據完全暴露出去,而且Content providers是以類似數據庫中表的方式將數據暴露。Content providers存儲和檢索數據,通過它可以讓所有的應用程序訪問到,這也是應用程序之間唯一共享數據的方法。
    要想使應用程序的數據公開化,可通過2種方法:創建一個屬於你自己的Content provider或者將你的數據添加到一個已經存在的Content provider中,前提是有相同數據類型並且有寫入Content provider的權限。
    如何通過一套標準及統一的接口獲取其他應用程序暴露的數據?
    Android提供了ContentResolver,外界的程序可以通過ContentResolver接口訪問ContentProvider提供的數據。

  • Service和Thread的區別?

    答:servie是系統的組件,它由系統進程託管(servicemanager);它們之間的通信類似於client和server,是一種輕量級的ipc通信,這種通信的載體是binder,它是在linux層交換信息的一種ipc。而thread是由本應用程序託管。1). Thread:Thread 是程序執行的最小單元,它是分配CPU的基本單位。可以用 Thread 來執行一些異步的操作。

    2). Service:Service 是android的一種機制,當它運行的時候如果是Local Service,那麼對應的 Service 是運行在主進程的 main 線程上的。如:onCreate,onStart 這些函數在被系統調用的時候都是在主進程的 main 線程上運行的。如果是Remote Service,那麼對應的 Service 則是運行在獨立進程的 main 線程上。

  • Android本身的api並未聲明會拋出異常,則其在運行時有無可能拋出runtime異常,你遇到過嗎?諾有的話會導致什麼問題?如何解決?

    答:會,比如nullpointerException。我遇到過,比如textview.setText()時,textview沒有初始化。會導致程序無法正常運行出現forceclose。打開控制檯查看logcat信息找出異常信息並修改程序。

  • IntentService有何優點?

    答:Acitivity的進程,當處理Intent的時候,會產生一個對應的Service; Android的進程處理器現在會儘可能的不kill掉你;非常容易使用

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

    答:重寫onSaveInstanceState()方法,在此方法中保存需要保存的數據,該方法將會在activity被回收之前調用。通過重寫onRestoreInstanceState()方法可以從中提取保存好的數據

  • 如何將一個Activity設置成窗口的樣式

    答:中配置:android :theme=”@android:style/Theme.Dialog”
    另外android:theme=”@android:style/Theme.Translucent” 是設置透明

  • 如何退出Activity?如何安全退出已調用多個Activity的Application?

    答:對於單一Activity的應用來說,退出很簡單,直接finish()即可。當然,也可以用killProcess()和System.exit()這樣的方法。
    對於多個activity,1、記錄打開的Activity:每打開一個Activity,就記錄下來。在需要退出時,關閉每一個Activity即可。2、發送特定廣播:在需要結束應用時,發送一個特定的廣播,每個Activity收到廣播後,關閉即可。3、遞歸退出:在打開新的Activity時使用startActivityForResult,然後自己加標誌,在onActivityResult中處理,遞歸關閉。爲了編程方便,最好定義一個Activity基類,處理這些共通問題。
    在2.1之前,可以使用ActivityManager的restartPackage方法。
    它可以直接結束整個應用。在使用時需要權限android.permission.RESTART_PACKAGES。
    注意不要被它的名字迷惑。
    可是,在2.2,這個方法失效了。在2.2添加了一個新的方法,killBackground Processes(),需要權限 android.permission.KILL_BACKGROUND_PROCESSES。可惜的是,它和2.2的restartPackage一樣,根本起不到應有的效果。
    另外還有一個方法,就是系統自帶的應用程序管理裏,強制結束程序的方法,forceStopPackage()。它需要權限android.permission.FORCE_STOP_PACKAGES。並且需要添加android:sharedUserId=”android.uid.system”屬性。同樣可惜的是,該方法是非公開的,他只能運行在系統進程,第三方程序無法調用。
    因爲需要在Android.mk中添加LOCAL_CERTIFICATE := platform。
    而Android.mk是用於在Android源碼下編譯程序用的。
    從以上可以看出,在2.2,沒有辦法直接結束一個應用,而只能用自己的辦法間接辦到。
    現提供幾個方法,供參考:
    1、拋異常強制退出:
    該方法通過拋異常,使程序Force Close。
    驗證可以,但是,需要解決的問題是,如何使程序結束掉,而不彈出Force Close的窗口。
    2、記錄打開的Activity:
    每打開一個Activity,就記錄下來。在需要退出時,關閉每一個Activity即可。
    3、發送特定廣播:
    在需要結束應用時,發送一個特定的廣播,每個Activity收到廣播後,關閉即可。
    4、遞歸退出
    在打開新的Activity時使用startActivityForResult,然後自己加標誌,在onActivityResult中處理,遞歸關閉。
    除了第一個,都是想辦法把每一個Activity都結束掉,間接達到目的。但是這樣做同樣不完美。你會發現,如果自己的應用程序對每一個Activity都設置了nosensor,在兩個Activity結束的間隙,sensor可能有效了。但至少,我們的目的達到了,而且沒有影響用戶使用。爲了編程方便,最好定義一個Activity基類,處理這些共通問題。

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

    答:全稱是:Android Interface Define Language
    在Android中, 每個應用程序都可以有自己的進程. 在寫UI應用的時候, 經常要用到Service. 在不同的進程中, 怎樣傳遞對象呢?顯然, Java中不允許跨進程內存共享. 因此傳遞對象, 只能把對象拆分成操作系統能理解的簡單形式, 以達到跨界對象訪問的目的. 在J2EE中,採用RMI的方式, 可以通過序列化傳遞對象. 在Android中, 則採用AIDL的方式. 理論上AIDL可以傳遞Bundle,實際上做起來卻比較麻煩。
    AIDL(AndRoid接口描述語言)是一種藉口描述語言; 編譯器可以通過aidl文件生成一段代碼,通過預先定義的接口達到兩個進程內部通信進程的目的. 如果需要在一個Activity中, 訪問另一個Service中的某個對象, 需要先將對象轉化成AIDL可識別的參數(可能是多個參數), 然後使用AIDL來傳遞這些參數, 在消息的接收端, 使用這些參數組裝成自己需要的對象.
    AIDL的IPC的機制和COM或CORBA類似, 是基於接口的,但它是輕量級的。它使用代理類在客戶端和實現層間傳遞值. 如果要使用AIDL, 需要完成2件事情: 1. 引入AIDL的相關類.; 2. 調用aidl產生的class.

  • 請解釋下Android程序運行時權限與文件系統權限的區別

    答:運行時權限Dalvik( android授權)
    文件系統 linux 內核授權

  • 系統上安裝了多種瀏覽器,能否指定某瀏覽器訪問指定頁面?請說明原由

    答:通過直接發送Uri把參數帶過去,或者通過manifest裏的intentfilter裏的data屬性

  • android系統的優勢和不足

    答:Android平臺手機 5大優勢:
    一、開放性
    在優勢方面,Android平臺首先就是其開發性,開發的平臺允許任何移動終端廠商加入到Android聯盟中來。顯著的開放性可以使其擁有更多的開發者,隨着用戶和應用的日益豐富,一個嶄新的平臺也將很快走向成熟。開放性對於Android的發展而言,有利於積累人氣,這裏的人氣包括消費者和廠商,而對於消費者來講,隨大的受益正是豐富的軟件資源。開放的平臺也會帶來更大競爭,如此一來,消費者將可以用更低的價位購得心儀的手機。
    二、掙脫運營商的束縛
    在過去很長的一段時間,特別是在歐美地區,手機應用往往受到運營商制約,使用什麼功能接入什麼網絡,幾乎都受到運營商的控制。從去年iPhone 上市 ,用戶可以更加方便地連接網絡,運營商的制約減少。隨着EDGE、HSDPA這些2G至3G移動網絡的逐步過渡和提升,手機隨意接入網絡已不是運營商口中的笑談,當你可以通過手機IM軟件方便地進行即時聊天時,再回想不久前天價的彩信和圖鈴下載業務,是不是像噩夢一樣?互聯網巨頭Google推動的Android終端天生就有網絡特色,將讓用戶離互聯網更近。
    三、豐富的硬件選擇
    這一點還是與Android平臺的開放性相關,由於Android的開放性,衆多的廠商會推出千奇百怪,功能特色各具的多種產品。功能上的差異和特色,卻不會影響到數據同步、甚至軟件的兼容,好比你從諾基亞 Symbian風格手機 一下改用蘋果 iPhone ,同時還可將Symbian中優秀的軟件帶到iPhone上使用、聯繫人等資料更是可以方便地轉移,是不是非常方便呢?
    四、不受任何限制的開發商
    Android平臺提供給第三方開發商一個十分寬泛、自由的環境,不會受到各種條條框框的阻擾,可想而知,會有多少新穎別緻的軟件會誕生。但也有其兩面性,血腥、暴力、情色方面的程序和遊戲如可控制正是留給Android難題之一。
    五、無縫結合的Google應用
    如今叱詫互聯網的Google已經走過10年度歷史,從搜索巨人到全面的互聯網滲透,Google服務如地圖、郵件、搜索等已經成爲連接用戶和互聯網的重要紐帶,而Android平臺手機將無縫結合這些優秀的Google服務。

    再說Android的5大不足:
    一、安全和隱私
    由於手機 與互聯網的緊密聯繫,個人隱私很難得到保守。除了上網過程中經意或不經意留下的個人足跡,Google這個巨人也時時站在你的身後,洞穿一切,因此,互聯網的深入將會帶來新一輪的隱私危機。
    二、首先開賣Android手機的不是最大運營商
    衆所周知,T-Mobile在23日,於美國紐約發佈 了Android首款手機G1。但是在北美市場,最大的兩家運營商乃AT&T和Verizon,而目前所知取得Android手機銷售權的僅有 T-Mobile和Sprint,其中T-Mobile的3G網絡相對於其他三家也要遜色不少,因此,用戶可以買賬購買G1,能否體驗到最佳的3G網絡服務則要另當別論了!
    三、運營商仍然能夠影響到Android手機
    在國內市場,不少用戶對購得移動定製機不滿,感覺所購的手機被人塗畫了廣告一般。這樣的情況在國外市場同樣出現。Android手機的另一發售運營商Sprint就將在其機型中內置其手機商店程序。
    四、同類機型用戶減少
    在不少手機論壇都會有針對某一型號的子論壇,對一款手機的使用心得交流,並分享軟件資源。而對於Android平臺手機,由於廠商豐富,產品類型多樣,這樣使用同一款機型的用戶越來越少,缺少統一機型的程序強化。舉個稍顯不當的例子,現在山寨機氾濫,品種各異,就很少有專門針對某個型號山寨機的討論和羣組,除了哪些功能異常搶眼、頗受追捧的機型以外。
    五、過分依賴開發商缺少標準配置
    在使用PC端的Windows Xp系統的時候,都會內置微軟Windows Media Player這樣一個瀏覽器程序,用戶可以選擇更多樣的播放器,如Realplay或暴風影音等。但入手開始使用默認的程序同樣可以應付多樣的需要。在 Android平臺中,由於其開放性,軟件更多依賴第三方廠商,比如Android系統的SDK中就沒有內置音樂 播放器,全部依賴第三方開發,缺少了產品的統一性。

  • Android dvm的進程和Linux的進程, 應用程序的進程是否爲同一個概念

    答:DVM指dalivk的虛擬機。每一個Android應用程序都在它自己的進程中運行,都擁有一個獨立的Dalvik虛擬機實例。而每一個DVM都是在Linux 中的一個進程,所以說可以認爲是同一個概念。

  • sim卡的EF文件是什麼?有何作用?

    答:sim卡的文件系統有自己規範,主要是爲了和手機通訊,sim本 身可以有自己的操作系統,EF就是作存儲並和手機通訊用的

  • 嵌入式操作系統內存管理有哪幾種, 各有何特性?

     答:頁式,段式,段頁,用到了MMU,虛擬空間等技術

  • 什麼是嵌入式實時操作系統, Android 操作系統屬於實時操作系統嗎?

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

  • 一條最長的短信息約佔多少byte?

     答:中文70(包括標點),英文160,160個字節。  

  • 如何將SQLite數據庫(dictionary.db文件)與apk文件一起發佈?

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

  • 如何將打開res aw目錄中的數據庫文件?

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

  • DDMS和TraceView的區別?

    答:DDMS是一個程序執行查看器,在裏面可以看見線程和堆棧等信息,TraceView是程序性能分析器 。

  • java中如何引用本地語言 ?

    答:可以用JNI(java native interface java 本地接口)接口 。

  • 談談Android的IPC(進程間通信)機制

    IPC是內部進程通信的簡稱, 是共享”命名管道”的資源。Android中的IPC機制是爲了讓Activity和Service之間可以隨時的進行交互,故在Android中該機制,只適用於Activity和Service之間的通信,類似於遠程方法調用,類似於C/S模式的訪問。通過定義AIDL接口文件來定義IPC接口。Servier端實現IPC接口,Client端調用IPC接口本地代理。

  • NDK是什麼?

    NDK是一些列工具的集合,NDK提供了一系列的工具,幫助開發者迅速的開發C/C++的動態庫,並能自動將so和java 應用打成apk包。
    NDK集成了交叉編譯器,並提供了相應的mk文件和隔離cpu、平臺等的差異,開發人員只需簡單的修改mk文件就可以創建出so

  • Android系統啓動過程,App啓動過程

    從桌面點擊到activity啓動的過程
    1、Launcher線程捕獲onclick的點擊事件,調用Launcher.startActivitySafely,進一步調用Launcher.startActivity,最後調用父類Activity的startActivity。
    2、Activity和ActivityManagerService交互,引入Instrumentation,將啓動請求交給Instrumentation,調用Instrumentation.execStartActivity。
    3、調用ActivityManagerService的startActivity方法,這裏做了進程切換(具體過程請查看源碼)。
    4、開啓Activity,調用onCreate方法

  • View繪畫機制

    View的繪製主要涉及三個方法:onMeasure()、onLayout()、onDraw()
    1、onMeasure主要用於計算view的大小,onLayout主要用於確定view在ContentView中的位置,onDraw主要是繪製View。
    2、在執行onMeasure()、onLayout()方法時都會通過相應的標誌位或者對應的座標點來判斷是否需要執行對應的函數,如我們經常調用的invalidate方法就只會執行onDraw方法,因爲此時的視圖大小和位置均未發生變化,除非調用requestLayout方法完整強制進行view的繪製,從而執行上面三個方法。
    3、繼承ViewGroup子類必須實現onLayout方法

  • 事件傳遞機制

    android 事件處理機制總結,ScrollView ViewPager ListView GridView嵌套小結
    當手指觸摸到屏幕時,系統就會調用相應View的onTouchEvent,並傳入一系列的action。
    dispatchTouchEvent的執行順序爲:
    首先觸發activity的dispatchTouchEvent,然後觸發activity的onUserInteraction
    然後觸發layout的dispatchTouchEvent,然後觸發layout的onInterceptTouchEvent
    這就解釋了重寫ViewGroup時必須調用super.dispatchTouchEvent();

    (1)dispatchTouchEvent:
    此方法一般用於初步處理事件,因爲動作是由此分發,所以通常會調用super.dispatchTouchEvent。這樣就會繼續調用onInterceptTouchEvent,再由onInterceptTouchEvent決定事件流向。

    (2)onInterceptTouchEvent:
    若返回值爲true事件會傳遞到自己的onTouchEvent();若返回值爲false傳遞到下一個View的dispatchTouchEvent();前面說了底層的View能夠接收到這次的事件有一個前提條件:在父層允許的情況下。假設不改變父層級的dispatch方法,在系統調用底層onTouchEvent之前會調用父View的onInterceptTouchEvent方法判斷,父層View是否要截獲本次touch事件之後的action。如果onInterceptTouchEvent返回了true,那麼本次touch事件之後的所有action都不會向深層的View傳遞,統統都會傳給父層View的onTouchEvent,就是說父層已經截獲了這次touch事件,之後的action也不必詢問onInterceptTouchEvent,在這次的touch事件之後發出的action時onInterceptTouchEvent不會再被調用,直到下一次touch事件的來臨。如果onInterceptTouchEvent返回false,那麼本次action將發送給更深層的View,並且之後的每一次action都會詢問父層的onInterceptTouchEvent需不需要截獲本次touch事件。只有ViewGroup纔有onInterceptTouchEvent方法,因爲一個普通的View肯定是位於最深層的View,只有ViewGroup纔有onInterceptTouchEvent方法,因爲一個普通的View肯定是位於最深層的View,touch能夠傳到這裏已經是最後一站了,肯定會調用View的onTouchEvent()。

    (3)onTouchEvent():
    若返回值爲true,事件由自己消耗,後續動作讓其處理;若返回值爲false,自己不消耗事件了,向上返回讓其他的父View的onTouchEvent接受處理。當有多個層級的View時,在父層級允許的情況下,這個action會一直傳遞直到遇到最深層的View。所以touch事件最先調用的是最底層View的onTouchEvent,如果View的onTouchEvent接收到某個touch action並做了相應處理,最後有兩種返回方式return true和return false;return true會告訴系統當前的View需要處理這次的touch事件,以後的系統發出的ACTION_MOVE,ACTION_UP還是需要繼續監聽並接收的,並且這次的action已經被處理掉了,父層的View是不可能觸發onTouchEvent的了。所以每一個action最多只能有一個onTouchEvent接口返回true。如果返回false,便會通知系統,當前View不關心這一次的touch事件,此時這個action會傳向父級,調用父級View的onTouchEvent。但是這一次的touch事件之後發出任何action,該View都不在接受,onTouchEvent在這一次的touch事件中再也不會觸發,也就是說一旦View返回false,那麼之後的ACTION_MOVE,ACTION_UP等ACTION就不會在傳入這個View,但是下一次touch事件的action還是會傳進來的。

  • Android幾種進程

    1、前臺進程: 即與用戶正在交互的Activity或者Activity用到的Service等,如果系統內存不足時前臺進程是最後被殺死的
    2、可見線程:可以是處於暫停狀態(onPause)的Activity或者綁定在其上的Service,即被用戶可見,但由於失去了焦點而不能與用戶交互
    3、服務進程:其中運行着使用startService方法啓動的Service,雖然不被用戶可見,但是卻是用戶關係的,例如用戶正在非音樂界面聽的音樂或者正在非下載頁面自己下載的文件等,當系統要用空間運行前兩者進程時纔會被終止
    4、後臺進程:其中運行着執行onStop方法而停止的程序,但是卻不是用戶當前關心的,例如後臺掛着的QQ,這樣的進程系統一旦沒有內存就首先被殺死。
    5、空進程:不包含任何應用程序的程序組件的進程,這樣的進程系統是一般不會讓他存在的。

    如何避免後臺進程被殺死?
    1、調用startForegound,讓你的Service所在的進程成爲前臺進程
    2、Service的onStartCommand返回START_STICKY或START_REDELIVER_INTENT
    3、Service的onDestroy裏面重新啓動自己

  • SurfaceView和View的最本質的區別

    SurfaceView是在一個新起的單獨線程中可以重新繪製畫面,而view必須在UI的主線程中更新畫面。

    在UI的主線程中更新畫面可能會引發問題,比如你更新的時間過長,那麼你的主UI線程就會被你正在畫的函數阻塞。那麼將無法響應按鍵、觸屏等消息。當使用SurfaceView由於是在新的線程中更新畫面所以不會阻塞你的UI主線程。但這也帶來了另外一個問題,就是事件同步。比如你觸屏了一下,你需要SurfaceView中thread處理,一般就需要有一個event queue的設計來保存touchevent,這會稍稍複雜一點,因爲涉及到線程安全。

  • 如何理解Activity,View,Window三者之間的關係?

    1:Activity構造的時候會初始化一個Window,準確的說是PhoneWindow。
    2:這個PhoneWindow有一個“ViewRoot”,這個“ViewRoot”是一個View或者說ViewGroup,是最初始的根視圖。
    3:“ViewRoot”通過addView方法來一個個的添加View。比如TextView,Button等
    4:這些View的事件監聽,是由WindowManagerService來接受消息,並且回調Activity函數。比如onClickListener,onKeyDown等。

  • 什麼是三級緩存?

    網絡加載,不優先加載,速度慢,浪費流量
    本地緩存,次優先加載,速度快
    內存緩存,優先加載,速度最快

    三級緩存原理:
    首次加載 Android App 時,肯定要通過網絡交互來獲取圖片,之後我們可以將圖片保存至本地SD卡和內存中
    之後運行 App 時,優先訪問內存中的圖片緩存,若內存中沒有,則加載本地SD卡中的圖片
    總之,只在初次訪問新內容時,才通過網絡獲取圖片資源

參考

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