標籤:android面試題 activity生命 aidl ndk ipc
總結了一些常見的Android面試題,內容會隨著不斷學習陸續增加。答案有誤地方希望大家可以指正 ,同時希望大家一起補充總結更多常見問題,謝謝^_^
1. 簡述Activity的生命週期
2. 請簡單說下對廣播接收者有哪些瞭解
3. view如何重新整理?簡述什麼是雙緩衝?
4、AIDL的全稱是什嗎?如何工作?能處理哪些類型的資料?
5、java中如何引用本地語言
6、談談Android的IPC(處理序間通訊)機制
7、NDK 是什麼
8、如何將SQLite資料庫(xxx.db檔案)與apk檔案一起發布
1.簡述Activity的生命週期
1、Activity可見並獲得焦點
當Activity啟動的時候,首先調用onCreate()、onStart(),onResume()方法,此時Activity對使用者來說,是可見的狀態
2、Activity可見但沒獲得焦點
當Activity從可見狀態變為被Dialog遮擋的狀態的時候,會調用onPause()方法,此時的Activity對使用者可見,但是不能獲得焦點
3、Activity不可見
當Activity從可見狀態變為被其他的Activity完全覆蓋或者是點擊Home進入背景時候,會依次調用onPause()//onStop()方法,如果在這個期間,系統記憶體不足,導致Activity被回收的話,還會調用onDestory()方法
4、Activity可見、沒獲得焦點狀態 –> Activity可見、獲得焦點狀態
當Activity從被Dialog遮擋的狀態恢複的時候,會調用onResume()方法,從而恢複可以點擊的狀態
5、Activity不可見、沒獲得焦點狀態 –> Activity可見、獲得焦點狀態
當Activity從被其他Activity遮擋或者是進入後台狀態後恢複,若沒有被系統回收,會依次調用onRestart()、onStart()、onResume()方法,恢複到可以與使用者進行互動的狀態
6、Activity不可見狀態–> Activity被回收 –> Activity可見、獲得焦點狀態
當Activity從被其他Activity遮擋或者進入後台,而且被系統回收的時候,此時恢複Activity,相當於重新開啟一個Activity,既調用onCreate()、onStart()//onResume()方法,從而恢複到可與使用者進行互動的狀態(期間可調用onRestoreInstanceState(),進行介面恢複)。
7、Activity可見、獲得焦點狀態 –> Activity可見、沒獲得焦點狀態 或 不可見狀態
在onPause()方法執行後,系統會停止一些消耗 CPU 的操作,因為這個時候程式的優先順序降低,很有可能被系統收回,所以我們應該在這個方法裡做資料持久化處理。儲存的資料可在 onResume() 裡讀出來,幫使用者恢複到之前的狀態。
8、Activity結束
在onDestroy()執行後,activity生命週期就結束了,可用 isFinishing()方法來判斷。如果此時有 Progress Dialog顯示,我們應該在onDestroy()裡 cancel 掉,否則線程結束的時候,調用Dialog 的 cancel 方法會拋異常。
2.請簡單說下對廣播接收者有哪些瞭解
廣播接收者(BroadcastReceiver)用於接收廣播Intent,廣播Intent的發送是通過調用Context.sendBroadcast()、Context.sendOrderedBroadcast()來實現的。通常一個廣播Intent可以被訂閱了此Intent的多個廣播接收者所接收,這個特性跟JMS中的Topic訊息接收者類似。要實現一個廣播接收者方法如下:
第一步:繼承BroadcastReceiver,並重寫onReceive()方法。
public class IncomingSMSReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { } }
第二步:訂閱指定的廣播Intent,訂閱者法有兩種:
第一種:使用代碼進行訂閱
IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");IncomingSMSReceiver receiver = new IncomingSMSReceiver();registerReceiver(receiver, filter);
第二種:在AndroidManifest.xml檔案中的節點裡進行訂閱:
<receiver android:name=".IncomingSMSReceiver"> <intent-filter> <action android:name="android.provider.Telephony.SMS_RECEIVED"/> </intent-filter> </receiver>
廣播類型:
廣播分為兩種不同的類型:“普通廣播(Normal broadcasts)”和“有序廣播(Ordered broadcasts)”。普通廣播是完全非同步,可以在同一時刻(邏輯上)被所有接收者接收到,訊息傳遞的效率比較高,但缺點是:接收者不能將處理結果傳遞給下一個接收者,並且無法終止廣播Intent的傳播;然而有序廣播是按照接收者聲明的優先順序別,被接收者依次接收廣播。如:A的層級高於B,B的層級高於C,那麼,廣播先傳給A,再傳給B,最後傳給C 。優先順序別聲明在intent-filter元素的android:priority屬性中,數越大優先順序別越高,取值範圍:-1000到1000,優先順序別也可以調用IntentFilter對象的setPriority()進行設定 。有序廣播的接收者可以終止廣播Intent的傳播,廣播Intent的傳播一旦終止,後面的接收者就無法接收到廣播。另外,有序廣播的接收者可以將資料傳遞給下一個接收者,如:A得到廣播後,可以往它的結果對象中存入資料,當廣播傳給B時,B可以從A的結果對象集合中得到A存入的資料。
Context.sendBroadcast() 發送的是普通廣播,所有訂閱者都有機會獲得並進行處理。
Context.sendOrderedBroadcast() 發送的是有序廣播,系統會根據接收者聲明的優先順序別按順序逐個執行接收者,前面的接收者有權終止廣播
BroadcastReceiver.abortBroadcast(),如果廣播被前面的接收者終止,後面的接收者就再也無法擷取到廣播。對於有序廣播,前面的接收者可以將資料通過setResultExtras(Bundle)方法存放進結果對象,然後傳給下一個接收者,下一個接收者通過代碼:Bundle bundle = getResultExtras(true))可以擷取上一個接收者存入在結果對象中的資料。
系統收到簡訊,發出的廣播屬於有序廣播。如果想阻止使用者收到簡訊,可以通過設定優先權,讓你們自訂的接收者先擷取到廣播,然後終止廣播,這樣使用者就接收不到簡訊了。
廣播接收者的響應:
在Android中,每次廣播訊息到來時都會建立BroadcastReceiver執行個體並執行onReceive() 方法, onReceive() 方法執行完後,BroadcastReceiver 的執行個體就會被銷毀。當onReceive() 方法在10秒內沒有執行完畢,Android會認為該程式無響應。所以在BroadcastReceiver裡不能做一些比較耗時的操作,否側會彈出ANR(Application No Response)的對話方塊。如果需要完成一項比較耗時的工作,應該通過發送Intent給Service,由Service來完成。這裡不能使用子線程來解決,因為BroadcastReceiver的生命週期很短,子線程可能還沒有結束BroadcastReceiver就先結束了。BroadcastReceiver一旦結束,此時BroadcastReceiver的所在進程很容易在系統需要記憶體時被優先殺死,因為它屬於空進程(沒有任何活動組件的進程)。如果它的宿主進程被殺死,那麼正在工作的子線程也會被殺死。所以採用子線程來解決是不可靠的。
public class IncomingSMSReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { //發送Intent啟動服務,由服務來完成比較耗時的操作 Intent service = new Intent(context, XxxService.class); context.startService(service); } }
常用廣播Intent:
除了簡訊到來廣播Intent,Android還有很多廣播Intent,如:開機啟動、電池電量變化、時間已經改變等廣播Intent。
接收開機啟動廣播Intent,在AndroidManifest.xml檔案中的節點裡訂閱此Intent:
<receiver android:name=".IncomingSMSReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"/> </intent-filter> </receiver>
並且要進行許可權聲明:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
接收電池電量變化廣播Intent ,在AndroidManifest.xml檔案中的節點裡訂閱此Intent:
<receiver android:name=".IncomingSMSReceiver"> <intent-filter> <action android:name="android.intent.action.BATTERY_CHANGED"/> </intent-filter> </receiver>
廣播接收者的生命週期及使用注意事項
1、廣播接收者的生命週期是非常短暫的,在接收到廣播的時候建立,onReceive()方法結束之後銷毀
2、廣播接收者中不要做一些耗時的工作,否則會彈出Application No Response錯誤對話方塊,耗時的較長的工作最好放在服務中完成
3、最好也不要在廣播接收者中建立子線程做耗時的工作,因為廣播接收者被銷毀後進程就成為了空進程,很容易被系統殺掉
3.view如何重新整理?簡述什麼是雙緩衝?
android中實現view的重新整理有兩個方法,一個是invalidate(),另一個是postInvalidate(),其中前者是在UI線程自身中使用,而後者在非UI線程中使用。
出現螢幕閃爍是圖形編程的一個常見問題。當進行複雜的繪製操作時會導致呈現的映像閃爍或具有其他不可接受的外觀。雙緩衝的使用解決這些問題。雙緩衝使用記憶體緩衝區來解決由多重繪製操作造成的閃爍問題。當使用雙緩衝時,首先在記憶體緩衝區裡完成所有繪製操作,而不是在螢幕上直接進行繪圖。當所有繪製操作完成後,把記憶體緩衝區完成的映像直接複製到螢幕。因為在螢幕上只執行一個圖形操作,所以消除了由複雜繪製操作造成的映像閃爍問題。
在android中實現雙緩衝,可以使用一個後台畫布backcanvas,先把所有繪製操作都在這上面進行。等圖畫好了,然後在把backcanvas拷貝到
與螢幕關聯的canvas上去,如下:
Bitmap bitmapBase = new Bitmap()Canvas backcanvas = new Canvas(bitmapBase)backcanvas.draw()...//畫圖Canvas c = lockCanvas(null);c.drawbitmap(bitmapBase);//把已經畫好的映像輸出到螢幕上unlock(c)....
4、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。
AIDL 的建立方法:
AIDL 文法很簡單,可以用來聲明一個帶一個或多個方法的介面,也可以傳遞參數和傳回值。
由於遠程調用的需要, 這些參數和傳回值並不是任何類型。下面是些 AIDL 支援的資料類型:
1、 不需要 import 聲明的簡單 Java 程式設計語言類型(int,boolean 等);
2、String, CharSequence 不需要特殊聲明;
3、 List, Map 和 Parcelables 類型, 這些類型內所包含的資料成員也只能是單一資料型別, String 等其他支援的類型。
5、java中如何引用本地語言
可以用JNI(java native interface java 本地介面)介面
6、談談Android的IPC(處理序間通訊)機制
IPC 是內部進程通訊的簡稱,是共用”具名管道”的資源。Android 中的 IPC 機制是為了
讓 Activity 和 Service 之間可以隨時的進行互動,故在 Android 中該機制,只適用於 Activity和 Service 之間的通訊,類似於遠程方法調用,類似於 C/S 模式的訪問。通過定義 AIDL 介面檔案來定義 IPC 介面。Servier 端實現 IPC 介面,Client 端調用 IPC 介面本地代理。
7、NDK 是什麼
NDK 是一些列工具的集合, NDK 提供了一系列的工具,協助開發人員迅速的開發 C/C++的動態庫,並能自動將 so 和 java 應用打成 apk 包。
NDK 整合了交叉編譯器,並提供了相應的 mk 檔案和隔離 cpu、平台等的差異,開發人員只需簡單的修改 mk 檔案就可以建立出 so。
8、如何將SQLite資料庫(xxx.db檔案)與apk檔案一起發布
可以將xxx.db檔案複製到Eclipse Android工程中的res aw目錄中。所有在res aw目錄中的檔案不會被壓縮,這樣可以直接提取該目錄中的檔案。可以將xxx.db檔案複製到res aw目錄中。
Android常見面試題(一)