Android面试基础一
Android面試基礎二-原理及常見問題
目錄
- 1、四大組件
- 1)Activity
- 2)Service
- 3)ContentProvider
- 4)Broadcast Receiver
- 2、四大組件的生命周期和簡單用法
- 1)Activity
- 2)Service
- 3)BroadcastReceiver
- 4)ContentProvider
- 3、Activity之間的通信方式
- 4、Activity各種情況下的生命周期
- 5、橫豎屏切換的時候,Activity 各種情況下的生命周期
- 6、Activity與Fragment之間生命周期比較
- 7、Activity上有Dialog的時候按Home鍵時的生命周期
- 8、兩個Activity 之間跳轉時必然會執行的是哪幾個方法?
- 9、前臺切換到后臺,然后再回到前臺,Activity生命周期回調方法。彈出Dialog,生命值周期回調方法。
- 10、Activity的四種啟動模式對比
- 11、Activity狀態保存于恢復
- 12、fragment各種情況下的生命周期
- 13、Fragment狀態保存onSaveInstanceState是哪個類的方法,在什么情況下使用?
- 14、Fragment.startActivityForResult是和FragmentActivity的startActivityForResult?
- 15、如何實現Fragment的滑動?
- 16、fragment之間傳遞數據的方式?
- 17、service和activity怎么進行數據交互?
- 18、說說ContentProvider、ContentResolver、ContentObserver 之間的關系
- 19、請描述一下廣播BroadcastReceiver的理解
- 20、廣播的分類
- 21、廣播使用的方式和場景
- 22、在manifest 和代碼中如何注冊和使用BroadcastReceiver?
- 23、本地廣播和全局廣播有什么差別?
- 24、AlertDialog,popupWindow,Activity區別
- 25、Application 和 Activity 的 Context 對象的區別
- 26、Android屬性動畫特性
- 27、如何導入外部數據庫?
- 28、談談對接口與回調的理解
- 29、介紹下SurfView
- 30、Android中數據存儲方式
1、四大組件
這是各大教程開頭的章節介紹,也是開發的基礎知識,甚至說是常識。
1)Activity
用戶可操作的可視化界面,為用戶提供一個完成操作指令的窗口。一個Activity通常是一個單獨的屏幕,Activity通過Intent來進行通信。Android中會維持一個Activity Stack,當一個新Activity創建時,它就會放到棧頂,這個Activity就處于運行狀態。
2)Service
運行在手機后臺,適合執行不需和用戶交互且還需長期運行的任務。
3)ContentProvider
內容提供者,使一個應用程序的指定數據集提供給其他應用程序,其他應用可通過ContentResolver類從該內容提供者中獲取或存入數據。它提供了一種跨進程數據共享的方式,當數據被修改后,ContentResolver接口的notifyChange函數通知那些注冊監控特定URI的ContentObserver對象。
如果ContentProvider和調用者在同一進程中,ContentProvider的方法(query/insert/update/delete等)和調用者在同一線程中;如果ContentProvider和調用者不在同一進程,ContentProvider方法會運行在它自身進程的一個Binder線程中。
4)Broadcast Receiver
廣播接收者,運用在應用程序間傳輸信息,可以使用廣播接收器來讓應用對一個外部事件做出響應。
2、四大組件的生命周期和簡單用法
1)Activity
onCreate()->onStart()->onResume()->onPause()->onStop()->onDestory()
onCreate():為Activity設置布局,此時界面還不可見;
onStart(): Activity可見但還不能與用戶交互,不能獲得焦點
onRestart(): 重新啟動Activity時被回調
onResume(): Activity可見且可與用戶進行交互
onPause(): 當前Activity暫停,不可與用戶交互,但還可見。在新Activity啟動前被系統調用保存現有的Activity中的持久數據、停止動畫等。
onStop(): 當Activity被新的Activity覆蓋不可見時被系統調用
onDestory(): 當Activity被系統銷毀殺掉或是由于內存不足時調用
2)Service
a)onBind方式綁定的:onCreate->onBind->onUnBind->onDestory(不管調用bindService幾次,onCreate只會調用一次,onStart不會被調用,建立連接后,service會一直運行,直到調用unBindService或是之前調用的bindService的Context不存在了,系統會自動停止Service,對應的onDestory會被調用)
b)startService啟動的:onCreate->onStartCommand->onDestory(start多次,onCreate只會被調用一次,onStart會調用多次,該service會在后臺運行,直至被調用stopService或是stopSelf)
c)又被啟動又被綁定的服務,不管如何調用onCreate()只被調用一次,startService調用多少次,onStart就會被調用多少次,而unbindService不會停止服務,必須調用stopService或是stopSelf來停止服務。必須unbindService和stopService(stopSelf)同時都調用了才會停止服務。
3)BroadcastReceiver
a) 動態注冊:存活周期是在Context.registerReceiver和Context.unregisterReceiver之間,BroadcastReceiver每次收到廣播都是使用注冊傳入的對象處理的。
b) 靜態注冊:進程在的情況下,receiver會正常收到廣播,調用onReceive方法;生命周期只存活在onReceive函數中,此方法結束,BroadcastReceiver就銷毀了。onReceive()只有十幾秒存活時間,在onReceive()內操作超過10S,就會報ANR。
進程不存在的情況,廣播相應的進程會被拉活,Application.onCreate會被調用,再調用onReceive。
4)ContentProvider
應該和應用的生命周期一樣,它屬于系統應用,應用啟動時,它會跟著初始化,應用關閉或被殺,它會跟著結束。
3、Activity之間的通信方式
通過Intent方式傳遞參數跳轉
通過廣播方式
通過接口回調方式
借助類的靜態變量或全局變量
借助SharedPreference或是外部存儲,如數據庫或本地文件
4、Activity各種情況下的生命周期
兩個Activity(A->B)切換(B正常的Activity)的生命周期:onPause(A)->onCreate(B)->onStart(B)->onResume(B)->oStop(A)
這時如果按回退鍵回退到A onPause(B)->onRestart(A)->onStart(A)->onResume(A)->oStop(B)
如果在切換到B后調用了A.finish(),則會走到onDestory(A),這時點回退鍵會退出應用
兩個Activity(A->B)切換(B透明主題的Activity或是Dialog風格的Acivity)的生命周期:onPause(A)->onCreate(B)->onStart(B)->onResume(B)
這時如果回退到A onPause(B)->onResume(A)->oStop(B)->onDestory(B)
Activity(A)啟動后點擊Home鍵再回到應用的生命周期:onPause(A)->oStop(A)->onRestart(A)->onStart(A)->onResume(A)
5、橫豎屏切換的時候,Activity 各種情況下的生命周期
切換橫屏時:
onSaveInstanceState->onPause->onStop->onDestory->onCreate->onStart->onRestoreInstanceState->onResume
切換豎屏時:會打印兩次相同的log
onSaveInstanceState->onPause->onStop->onDestory->onCreate->onStart->onRestoreInstanceState->onResume->onSaveInstanceState->onPause->onStop->onDestory->onCreate->onStart->onRestoreInstanceState->onResume
如果在AndroidMainfest.xml中修改該Activity的屬性,添加android:configChanges=“orientation”
橫豎屏切換,打印的log一樣,同1)
如果AndroidMainfest.xml中該Activity中的android:configChanges=“orientation|keyboardHidden”,則只會打印
onConfigurationChanged->
6、Activity與Fragment之間生命周期比較
Fragment生命周期:onAttach->onCreate->onCreateView->onActivityCreated->onStart->onResume->onPause->onStop->onDestoryView->onDestory->onDetach
切換到該Fragment:onAttach->onCreate->onCreateView->onActivityCreated->onStart->onResume
按下Power鍵:onPause->onSaveInstanceState->onStop
點亮屏幕解鎖:onStart->onRestoreInstanceState->onResume
切換到其他Fragment: onPause->onStop->onDestoryView
切回到該Fragment: onCreateView->onActivityCreated->onStart->onResume
退出應用:onPause->onStop->onDestoryView->onDestory->onDetach
7、Activity上有Dialog的時候按Home鍵時的生命周期
AlertDialog并不會影響Activity的生命周期,按Home鍵后才會使Activity走onPause->onStop,AlertDialog只是一個組件,并不會使Activity進入后臺。
8、兩個Activity 之間跳轉時必然會執行的是哪幾個方法?
前一個Activity的onPause,后一個Activity的onResume
9、前臺切換到后臺,然后再回到前臺,Activity生命周期回調方法。彈出Dialog,生命值周期回調方法。
前臺切換到后臺,會執行onPause->onStop,再回到前臺,會執行onRestart->onStart->onResume
彈出Dialog,并不會影響Activity生命周期
10、Activity的四種啟動模式對比
standard:標準啟動模式(默認),每啟動一次Activity,都會創建一個實例,即使從ActivityA startActivity ActivityA,也會再次創建A的實例放于棧頂,當回退時,回到上一個ActivityA的實例。
singleTop:棧頂復用模式,每次啟動Activity,如果待啟動的Activity位于棧頂,則不會重新創建Activity的實例,即不會走onCreate->onStart,會直接進入Activity的onPause->onNewIntent->onResume方法
singleInstance: 單一實例模式,整個手機操作系統里只有一個該Activity實例存在,沒有其他Actvity,后續請求均不會創建新的Activity。若task中存在實例,執行實例的onNewIntent()。應用場景:鬧鐘、瀏覽器、電話
singleTask:棧內復用,啟動的Activity如果在指定的taskAffinity的task棧中存在相應的實例,則會把它上面的Activity都出棧,直到當前Activity實例位于棧頂,執行相應的onNewIntent()方法。如果指定的task不存在,創建指定的taskAffinity的task,taskAffinity的作用,進入指寫taskAffinity的task,如果指定的task存在,將task移到前臺,如果指定的task不存在,創建指定的taskAffinity的task. 應用場景:應用的主頁面
11、Activity狀態保存于恢復
Activity被主動回收時,如按下Back鍵,系統不會保存它的狀態,只有被動回收時,雖然這個Activity實例已被銷毀,但系統在新建一個Activity實例時,會帶上先前被回收Activity的信息。在當前Activity被銷毀前調用onSaveInstanceState(onPause和onStop之間保存),重新創建Activity后會在onCreate后調用onRestoreInstanceState(onStart和onResume之間被調用),它們的參數Bundle用來數據保存和讀取的。
保存View狀態有兩個前提:View的子類必須實現了onSaveInstanceState; 必須要設定Id,這個ID作為Bundle的Key
12、fragment各種情況下的生命周期
正常情況下的生命周期:onAttach->onCreate->onCreateView->onActivityCreated->onStart->onResume->onPause->onStop->onDestoryView->onDestory->onDetach
1)Fragment在Activity中replace onPause(舊)->onAttach->onCreate->onCreateView->onActivityCreated->onStart->onResume->onStop(舊)->onDestoryView(舊)
如果添加到backStack中,調用remove()方法fragment的方法會走到onDestoryView,但不會執行onDetach(),即fragment本身的實例是存在的,成員變量也存在,但是view被銷毀了。如果新替換的Fragment已在BackStack中,則不會執行onAttach->onCreate
13、Fragment狀態保存onSaveInstanceState是哪個類的方法,在什么情況下使用?
在對應的FragmentActivity.onSaveInstanceState方法會調用FragmentController.saveAllState,其中會對mActive中各個Fragment的實例狀態和View狀態分別進行保存.當Activity在做狀態保存和恢復的時候, 在它其中的fragment自然也需要做狀態保存和恢復.
參考文章:Android Fragment使用(三) Activity, Fragment, WebView的狀態保存和恢復
14、Fragment.startActivityForResult是和FragmentActivity的startActivityForResult?
如果希望在Fragment的onActivityResult接收數據,就要調用Fragment.startActivityForResult, 而不是Fragment.getActivity().startActivityForResult。Fragment.startActivityForResult->FragmentActivitymHost.HostCallbacks.onStartActivityFromFragment->FragmentActivity.startActivityFromFragment。如果request=-1則直接調用FragmentActivity.startActivityForResult,它會重新計算requestCode,使其大于0xfffff。
參考文章:徹底搞懂startActivityForResult在FragmentActivity和Fragment中的異同
15、如何實現Fragment的滑動?
ViewPager+FragmentPagerAdapter+List
16、fragment之間傳遞數據的方式?
在相應的fragment中編寫方法,在需要回調的fragment里獲取對應的Fragment實例,調用相應的方法;
采用接口回調的方式進行數據傳遞;
a) 在Fragment1中創建一個接口及接口對應的set方法;
b) 在Fragment1中調用接口的方法;c)在Fragment2中實現該接口;
利用第三方開源框架EventBus
17、service和activity怎么進行數據交互?
通過bindService啟動服務,可以在ServiceConnection的onServiceConnected中獲取到Service的實例,這樣就可以調用service的方法,如果service想調用activity的方法,可以在service中定義接口類及相應的set方法,在activity中實現相應的接口,這樣service就可以回調接口言法;
通過廣播方式
18、說說ContentProvider、ContentResolver、ContentObserver 之間的關系
ContentProvider實現各個應用程序間數據共享,用來提供內容給別的應用操作。如聯系人應用中就使用了ContentProvider,可以在自己應用中讀取和修改聯系人信息,不過需要獲取相應的權限。它也只是一個中間件,真正的數據源是文件或SQLite等。
ContentResolver內容解析者,用于獲取內容提供者提供的數據,通過ContentResolver.notifyChange(uri)發出消息
ContentObserver內容監聽者,可以監聽數據的改變狀態,觀察特定Uri引起的數據庫變化,繼而做一些相應的處理,類似于數據庫中的觸發器,當ContentObserver所觀察的Uri發生變化時,便會觸發它。
19、請描述一下廣播BroadcastReceiver的理解
BroadcastReceiver是一種全局監聽器,用來實現系統中不同組件之間的通信。有時候也會用來作為傳輸少量而且發送頻率低的數據,但是如果數據的發送頻率比較高或者數量比較大就不建議用廣播接收者來接收了,因為這樣的效率很不好,因為BroadcastReceiver接收數據的開銷還是比較大的。
20、廣播的分類
普通廣播:完全異步的,可以在同一時刻(邏輯上)被所有接收者接收到,消息傳遞的效率比較高,并且無法中斷廣播的傳播。
有序廣播:發送有序廣播后,廣播接收者將按預先聲明的優先級依次接收Broadcast。優先級高的優先接收到廣播,而在其onReceiver()執行過程中,廣播不會傳播到下一個接收者,此時當前的廣播接收者可以abortBroadcast()來終止廣播繼續向下傳播,也可以將intent中的數據進行修改設置,然后將其傳播到下一個廣播接收者。 sendOrderedBroadcast(intent, null);//發送有序廣播
粘性廣播:sendStickyBroadcast()來發送該類型的廣播信息,這種的廣播的最大特點是,當粘性廣播發送后,最后的一個粘性廣播會滯留在操作系統中。如果在粘性廣播發送后的一段時間里,如果有新的符合廣播的動態注冊的廣播接收者注冊,將會收到這個廣播消息,雖然這個廣播是在廣播接收者注冊之前發送的,另外一點,對于靜態注冊的廣播接收者來說,這個等同于普通廣播。
21、廣播使用的方式和場景
App全局監聽:在AndroidManifest中靜態注冊的廣播接收器,一般我們在收到該消息后,需要做一些相應的動作,而這些動作與當前App的組件,比如Activity或者Service的是否運行無關,比如我們在集成第三方Push SDK時,一般都會添加一個靜態注冊的BroadcastReceiver來監聽Push消息,當有Push消息過來時,會在后臺做一些網絡請求或者發送通知等等。
組件局部監聽:這種主要是在Activity或者Service中使用registerReceiver()動態注冊的廣播接收器,因為當我們收到一些特定的消息,比如網絡連接發生變化時,我們可能需要在當前Activity頁面給用戶一些UI上的提示,或者將Service中的網絡請求任務暫停。所以這種動態注冊的廣播接收器適合特定組件的特定消息處理。
22、在manifest 和代碼中如何注冊和使用BroadcastReceiver?
23、本地廣播和全局廣播有什么差別?
LocalBroadcastReceiver僅在自己的應用內發送接收廣播,也就是只有自己的應用能收到,數據更加安全。廣播只在這個程序里,而且效率更高。只能動態注冊,在發送和注冊的時候采用LocalBroadcastManager的sendBroadcast方法和registerReceiver方法。
全局廣播:發送的廣播事件可被其他應用程序獲取,也能響應其他應用程序發送的廣播事件(可以通過 exported–是否監聽其他應用程序發送的廣播 在清單文件中控制) 全局廣播既可以動態注冊,也可以靜態注冊。
24、AlertDialog,popupWindow,Activity區別
Popupwindow在顯示之前一定要設置寬高,Dialog無此限制。
Popupwindow默認不會響應物理鍵盤的back,除非顯示設置了popup.setFocusable(true);而在點擊back的時候,Dialog會消失。
Popupwindow不會給頁面其他的部分添加蒙層,而Dialog會。
Popupwindow沒有標題,Dialog默認有標題,可以通過dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);取消標題
二者顯示的時候都要設置Gravity。如果不設置,Dialog默認是Gravity.CENTER。
二者都有默認的背景,都可以通過setBackgroundDrawable(new ColorDrawable(android.R.color.transparent));去掉。
Popupwindow彈出后,取得了用戶操作的響應處理權限,使得其他UI控件不被觸發。而AlertDialog彈出后,點擊背景,AlertDialog會消失。
25、Application 和 Activity 的 Context 對象的區別
可以startService\BindService\sendBroadcast\registerBroadcast\load Resource values
一個應用Context的數量=Activity數量+Service數量+1(Application數量)
26、Android屬性動畫特性
可以對非View的對象進行動畫操作;
補間動畫只能實現移動、縮放、旋轉、淡入淡出,而無法擴展,如對背景顏色進行改變等,但是屬性動畫就可以;
屬性動畫真正改變了對象的屬性
27、如何導入外部數據庫?
android系統下數據庫應該存放在/data/data/com…(package name)/目錄下,通過FileInputStream讀取原數據庫,再用FileOutputStream把讀取到的東西寫入到那個目錄下。在原數據庫放在項目源碼的/res/raw/目錄下,建立一個DBManager類,
28、談談對接口與回調的理解
原理:先創建一個對象,再創建一個控制器對象,將回調對象需要被調用的方法告訴控制器對象,控制器對象負責檢查某個場景是否出現或某個條件是否滿足,當滿足時,自動調用回調對象方法。
29、介紹下SurfView
SurfaceView擁有獨立的繪圖表面Surface,它不與其宿主窗口共享一個Surface,由于擁有獨立的Surface,所以SurfaceView的UI就可以在一個單獨的線程中進行繪制。繪圖流程:在繪圖表面的基礎上創建一塊畫布,即獲得一個Canvas對象;利用Canvas類提供的繪圖接口在前面獲得的畫布上繪制任意的UI;將已填充好了的UI數據的畫布緩沖區提交給SurfaceFlinger服務,以便SurfaceFlinger服務可以將它合成到屏幕上。
優點:
使用步驟:
30、Android中數據存儲方式
SharedPreferences:用來存儲一些簡單的配置信息,如登錄的用戶名、密碼,采用map數據結構存儲。寫入的時候先調用edit()使其處于編輯態,再修改數據,最后用commit()來提交修改的數據。采用XML格式將數據存儲到設備上/data/data//shares_prefs下。只能在同一個包內使用,不能在不同包之間使用。
數據庫SQLite
SD卡,本地存儲:openFileInput()和openFileOutput()
使用ContentProvider存儲數據:可向其他應用共享數據
總結
以上是生活随笔為你收集整理的Android面试基础一的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Gensee SDK UserInfo类
- 下一篇: Gensee移动SDK之(二)协议