Android面试题(五) --重要
46. 注冊廣播有幾種方式,這些方式有何優缺點?請談談 Android 引入廣播機制的用意。
?Android 廣播機制(兩種注冊方法) 在 android 下,要想接受廣播信息,那么這個廣播接收器就得我們自己來實現了,我們可以 繼承 BroadcastReceiver,就可以有一個廣播接受器了。有個接受器還不夠,我們還得重寫 BroadcastReceiver 里面的 onReceiver 方法,當來廣播的時候我們要干什么,這就要我們自己 來實現,不過我們可以搞一個信息防火墻。具體的代碼: public class SmsBroadCastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Bundle bundle = intent.getExtras(); Object[] object = (Object[])bundle.get("pdus"); SmsMessage sms[]=new SmsMessage[object.length]; for(int i=0;i<object.length;i++) { sms[0] = SmsMessage.createFromPdu((byte[])object[i]); Toast.makeText(context, "來自"+sms[i].getDisplayOriginatingAddress()+" 的消 息是:"+sms[i].getDisplayMessageBody(), Toast.LENGTH_SHORT).show(); } //終止廣播, 在這里我們可以稍微處理, 根據用戶輸入的號碼可以實現短信防火墻。 abortBroadcast(); } } 當實現了廣播接收器,還要設置廣播接收器接收廣播信息的類型,這里是信息: android.provider.Telephony.SMS_RECEIVED 我們就可以把廣播接收器注冊到系統里面, 可以讓系統知道我們有個廣播接收器。 這里有 兩種,一種是代碼動態注冊: //生成廣播處理 smsBroadCastReceiver = new SmsBroadCastReceiver(); //實例化過濾器并設置要過濾的廣播 IntentFilter intentFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED"); //注冊廣播 BroadCastReceiverActivity.this.registerReceiver(smsBroadCastReceiver, intentFilter); 一種是在 AndroidManifest.xml 中配置廣播 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="spl.broadCastReceiver" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".BroadCastReceiverActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!--廣播注冊--> <receiver android:name=".SmsBroadCastReceiver"> <intent-filter android:priority="20"> <action android:name="android.provider.Telephony.SMS_RECEIVED"/> </intent-filter> </receiver> </application> <uses-sdk android:minSdkVersion="7" /> <!-- 權限申請 --> <uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission> </manifest> 兩種注冊類型的區別是: 1)第一種不是常駐型廣播,也就是說廣播跟隨程序的生命周期。 2)第二種是常駐型,也就是說當應用程序關閉后,如果有信息廣播來,程序也會被系 統調用自動運行。
?
47. 請解釋下在單線程模型中 Message、Handler、Message Queue、Looper 之間的關系。 Handler 簡介: 一個 Handler 允許你發送和處理 Message 和 Runable 對象,這些對象和一個線程的 MessageQueue 相關聯。 每一個線程實例和一個單獨的線程以及該線程的 MessageQueue 相關 聯。當你創建一個新的 Handler 時,它就和創建它的線程綁定在一起了。這里,線程我們也 可以理解為線程的 MessageQueue。從這一點上來看,Handler 把 Message 和 Runable 對象傳 遞給 MessageQueue,而且在這些對象離開 MessageQueue 時,Handler 負責執行他們。 Handler 有兩個主要的用途: (1)確定在將來的某個時間點執行一個或者一些 Message 和 Runnable 對象。 (2)在其他線程(不是 Handler 綁定線程)中排入一些要執行的動作。 Scheduling Message,即(1) ,可以通過以下方法完成: post(Runnable):Runnable 在 handler 綁定的線程上執行,也就是說不創建新線程。 postAtTime(Runnable,long): postDelayed(Runnable,long): sendEmptyMessage(int): sendMessage(Message): sendMessageAtTime(Message,long): sendMessageDelayed(Message,long): post 這個動作讓你把 Runnable 對象排入 MessageQueue,MessageQueue 受到這些消息的時候 執行他們,當然以一定的排序。sendMessage 這個動作允許你把 Message 對象排成隊列,這 些 Message 對象包含一些信息, Handler 的 hanlerMessage(Message)會處理這些 Message.當然, handlerMessage(Message)必須由 Handler 的子類來重寫。這是編程人員需要作的事。 當 posting 或者 sending 到一個 Hanler 時,你可以有三種行為:當 MessageQueue 準備好就處 理,定義一個延遲時間,定義一個精確的時間去處理。后兩者允許你實現 timeout,tick,和基 于時間的行為。 當你的應用創建一個新的進程時,主線程(也就是 UI 線程)自帶一個 MessageQueue,這個 MessageQueue 管理頂層的應用對象(像 activities,broadcast receivers 等)和主線程創建的窗 體。你可以創建自己的線程,并通過一個 Handler 和主線程進行通信。這和之前一樣,通過 post 和 sendmessage 來完成,差別在于在哪一個線程中執行這么方法。在恰當的時候,給定 的 Runnable 和 Message 將在 Handler 的 MessageQueue 中被 Scheduled。 Message 簡介: Message 類就是定義了一個信息,這個信息中包含一個描述符和任意的數據對象,這個信息 被用來傳遞給 Handler.Message 對象提供額外的兩個 int 域和一個 Object 域,這可以讓你在 大多數情況下不用作分配的動作。 盡管 Message 的構造函數是 public 的,但是獲取 Message 實例的最好方法是調用 Message.obtain(),或者 Handler.obtainMessage()方法,這些方法會從回收對象池中獲取一個。 MessageQueue 簡介: 這是一個包含 message 列表的底層類。Looper 負責分發這些 message。Messages 并不是直接 加到一個 MessageQueue 中,而是通過 MessageQueue.IdleHandler 關聯到 Looper。 你可以通過 Looper.myQueue()從當前線程中獲取 MessageQueue。 Looper 簡介: Looper 類被用來執行一個線程中的 message 循環。 默認情況, 沒有一個消息循環關聯到線程。 在線程中調用 prepare()創建一個 Looper,然后用 loop()來處理 messages,直到循環終止。 大多數和 message loop 的交互是通過 Handler。 下面是一個典型的帶有 Looper 的線程實現。 class LooperThread extends Thread { public Handler mHandler; public void run() { Looper.prepare(); mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; Looper.loop(); } }
?
48. AIDL 的全稱是什么?如何工作?能處理哪些類型的數據? AIDL 的英文全稱是 Android Interface Define Language 當 A 進程要去調用 B 進程中的 service 時,并實現通信,我們通常都是通過 AIDL 來操作的 A 工程: 首先我們在 net.blogjava.mobile.aidlservice 包中創建一個 RemoteService.aidl 文件,在里面我 們自定義一個接口, 含有方法 get。 ADT 插件會在 gen 目錄下自動生成一個 RemoteService.java 文件,該類中含有一個名為 RemoteService.stub 的內部類,該內部類中含有 aidl 文件接口的 get 方法。 說明一:aidl 文件的位置不固定,可以任意 然后定義自己的 MyService 類,在 MyService 類中自定義一個內部類去繼承 RemoteService.stub 這個內部類,實現 get 方法。在 onBind 方法中返回這個內部類的對象, 系統會自動將這個對象封裝成 IBinder 對象,傳遞給他的調用者。 其次需要在 AndroidManifest.xml 文件中配置 MyService 類,代碼如下: <!-- 注冊服務 --> <service android:name=".MyService"> <intent-filter> <!-- 指定調用 AIDL 服務的 ID --> <action android:name="net.blogjava.mobile.aidlservice.RemoteService" /> </intent-filter> </service> 為什么要指定調用 AIDL 服務的 ID,就是要告訴外界 MyService 這個類能夠被別的進程訪問, 只要別的進程知道這個 ID,正是有了這個 ID,B 工程才能找到 A 工程實現通信。 說明:AIDL 并不需要權限 B 工程: 首先我們要將 A 工程中生成的 RemoteService.java 文件拷貝到 B 工程中,在 bindService 方法中綁定 aidl 服務 綁定 AIDL 服務就是將 RemoteService 的 ID 作為 intent 的 action 參數。 說明:如果我們單獨將 RemoteService.aidl 文件放在一個包里,那個在我們將 gen 目 錄下的該包拷貝到 B 工程中。如果我們將 RemoteService.aidl 文件和我們的其他類存放在一 起,那么我們在 B 工程中就要建立相應的包,以保證 RmoteService.java 文件的報名正確, 我們不能修改 RemoteService.java 文件 bindService(new Inten("net.blogjava.mobile.aidlservice.RemoteService"), serviceConnection, Context.BIND_AUTO_CREATE); ServiceConnection 的 onServiceConnected(ComponentName name, IBinder service)方法 中的 service 參數就是 A 工程中 MyService 類中繼承了 RemoteService.stub 類的內部類的對象。
?
49. 請解釋下 Android 程序運行時權限與文件系統權限的區別。 運行時權限 Dalvik( android 授權) 文件系統 linux 內核授權
?
50. 系統上安裝了多種瀏覽器,能否指定某瀏覽器訪問指定頁面?請說明原由。 通過直接發送 Uri 把參數帶過去,或者通過 manifest 里的 intentfilter 里的 data 屬性 51. 你如何評價 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 中就沒有內置音樂 播放器,全部依賴第三方開發,缺 少了產品的統一性。
?
52. 什么是 ANR 如何避免它?
答:ANR:Application Not Responding,五秒 在 Android 中,活動管理器和窗口管理器這兩個系統服務負責監視應用程序的響應。當出現 下列情況時,Android 就會顯示 ANR 對話框了: 對輸入事件(如按鍵、觸摸屏事件)的響應超過 5 秒 意向接受器(intentReceiver)超過 10 秒鐘仍未執行完畢 Android 應用程序完全運行在一個獨立的線程中(例如 main)。這就意味著,任何在主線 程中運行的,需要消耗大量時間的操作都會引發 ANR。因為此時,你的應用程序已經沒有 機會去響應輸入事件和意向廣播(Intent broadcast)。
?因此,任何運行在主線程中的方法,都要盡可能的只做少量的工作。特別是活動生命周 期中的重要方法如 onCreate()和 onResume()等更應如此。潛在的比較耗時的操作,
如訪問 網絡和數據庫;或者是開銷很大的計算,比如改變位圖的大小,需要在一個單獨的子線程中 完成(或者是使用異步請求,如數據庫操作)。但這并不意味著你的主線程需要進入阻塞狀態 已等待子線程結束 -- 也不需要調用 Therad.wait()或者 Thread.sleep()方法。 取而代之的是, 主線程為子線程提供一個句柄(Handler), 讓子線程在即將結束的時候調用它(xing:可以參看 Snake 的例子,這種方法與以前我們所接觸的有所不同)。使用這種方法涉及你的應用程序, 能夠保證你的程序對輸入保持良好的響應, 從而避免因為輸入事件超過 5 秒鐘不被處理而產 生的 ANR。這種實踐需要應用到所有顯示用戶界面的線程,因為他們都面臨著同樣的超時 問題。
?
53. 什么情況會導致 Force Close ?如何避免?能否捕獲導致其的異常?
?答:一般像空指針啊,可以看起 logcat,然后對應到程序中 來解決錯誤
?
?55. 簡要解釋一下 activity、 intent 、intent filter、service、Broadcase、BroadcaseReceiver
?答:一個 activity 呈現了一個用戶可以操作的可視化用戶界面 一個 service 不包含可見的用戶界面,而是在后臺無限地運行 可以連接到一個正在運行的服務中, 連接后, 可以通過服務中暴露出來的借口與其進行 通信 一個 broadcast receiver 是一個接收廣播消息并作出回應的 component,broadcast receiver 沒有界面 intent:content provider 在接收到 ContentResolver 的請求時被激活。 activity, service 和 broadcast receiver 是被稱為 intents 的異步消息激活的。 一個 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 文件中聲明的。
?
56. IntentService 有何優點?
答:IntentService 的好處 * Acitivity 的進程,當處理 Intent 的時候,會產生一個對應的 Service * Android 的進程處理器現在會盡可能的不 kill 掉你 * 非常容易使用
?
57. 橫豎屏切換時候 activity 的生命周期?
?1、不設置 Activity 的 android:configChanges 時,切屏會重新調用各個生命周期,切橫 屏時會執行一次,切豎屏時會執行兩次 2、設置 Activity 的 android:configChanges="orientation"時,切屏還是會重新調用各個 生命周期,切橫、豎屏時只會執行一次 3、設置 Activity 的 android:configChanges="orientation|keyboardHidden"時,切屏不 會重新調用各個生命周期,只會執行 onConfigurationChanged 方法 如何將 SQLite 數據庫(dictionary.db 文件)與 apk 文件一起發布? 解答:可以將 dictionary.db 文件復制到 Eclipse Android 工程中的 res aw 目錄中。所有 在 res aw 目錄中的文件不會被壓縮,這樣可以直接提取該目錄中的文件。可以將 dictionary.db 文件復制到 res aw 目錄中
?
58. 如何將打開 res aw 目錄中的數據庫文件?
?解答:在 Android 中不能直接打開 res aw 目錄中的數據庫文件,而需要在程序第一次 啟動時將該文件復制到手機內存或 SD 卡的某個目錄中,然后再打開該數據庫文件。復制的 基本方法是使用 getResources().openRawResource 方法獲得 res aw 目錄中資源的 InputStream 對象,然后將該 InputStream 對象中的數據寫入其他的目錄中相應文件中。在 Android SDK 中可以使用 SQLiteDatabase.openOrCreateDatabase 方法來打開任意目錄中的 SQLite 數據庫文件。
轉載于:https://www.cnblogs.com/liuzenglong/archive/2011/10/22/2221054.html
總結
以上是生活随笔為你收集整理的Android面试题(五) --重要的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android audit2allow工
- 下一篇: python英文词频统计代码_pytho