Android面試系列之Android基礎知識
這兩天就要換工作了,為了拿到offer,是時候來一波面試準備了!希望自己能找到心儀的工作。也希望這篇部落格能幫助到大家。
本篇部落格是相對基礎的知識,雖然是基礎,但是很重要,你能保證你都記住了麼?
Activity相關
Activity是四大元件之一,應該是我們開發中接觸最多的元件了吧。那麼問題來了!
什麼是Activity?
Activity是Android中的一個元件,提供了一個介面用於和使用者互動,使使用者可以在介面上進行點選、滑動等操作。
Activity的四種狀態
running / paused / stopped / killed
running: 表明Activity處於活動(完全可見)狀態,使用者可以與螢幕進行互動,此時,Activity處於棧頂。
paused:
stopped: 表明activity處於不可見的狀態(例如:被另一個Activity完全覆蓋)。
killed: 表明Activity被系統回收了,
Activity生命週期
首先來一張經典的圖:
Activity生命週期大致可以分為四個場景:
1.Activity啟動–>onCreate()–>onStart()–onResume();
onCreate是Activity被建立的時候呼叫,是生命週期的第一個方法,在這裡我們可以做一些初始化操作。
onStart表明Activity正在啟動,此時處於使用者可見狀態,但是並不能與使用者互動
onResume表明Activity已經處於前臺狀態,可以與使用者互動了。
2.點選Home鍵–>onPause()–>onStop()
onPause:表明Activity處於paused狀態,此時Activity無法與使用者互動
onStop:一般在onPause後面執行,表明Activity處於完全不可見的狀態。
3.點選home後再次回到程式時–>onRestart()–>onStart()–>onResume()
onRestart:表明Activity正在重新啟動,從不可見狀態變為可見狀態
4.退出當前Activity–onPause()–>onStop()–>onDestory()
onDestory:表明Activity正在被銷燬,是整個生命週期方法中的最後一個方法,在該方法中我們可以做一些資源回收的工作。
android中的程序優先順序
前臺/可見/服務/後臺/空
前臺:包含正在處於和使用者互動的Activity或者是前臺Activity綁定了service
可見:activity處於可見狀態但不可與使用者進行互動
服務:包含一個service服務的程序
後臺:處於不可見的狀態下(比如按了home鍵)
空:沒有活躍的元件 知識為了快取的目的存在的,隨時都可能被系統殺掉
Android任務棧
用於儲存Activity,當用戶啟動Activity或者退出Activity的時候,都會在棧中做一些新增或刪除的操作。
Activity啟動模式
1.standard
預設的啟動模式,每次啟動Activity的時候都會建立一個新的例項。不會複用Activity,對記憶體消耗較大。
2.singleTop
棧頂複用模式,如果要建立的Activity已經在棧頂的話,那麼不會重新建立,直接複用,否則,仍然會重新建立。
3.singletask
棧內複用模式,如果要建立的Activity在棧內已經存在的話,不會重新建立,直接複用棧記憶體在的Activity,且會呼叫onNewIntent()方法,並且將該Activity以上的所有的Activity銷燬。
4.singleInstance
單一例項,獨享一個任務棧,整個手機作業系統裡面只有一個例項存在。用的較少。
scheme跳轉協議
android中的scheme是一種頁面內跳轉協議,通過自定義的scheme協議,可以方便的跳轉app中的各個頁面。通過scheme協議,服務端可以定製化告訴App跳轉到哪個頁面,可以通過通知欄訊息定製化跳轉頁面,也可以通過H5頁面跳轉頁面等。
Fragment相關
fragment在平時專案開發中用的也非常多,是Android3.0後引入的,起初是為了在大螢幕上更靈活的去展現ui。現在通常使用的方式是fragment+viewpager. fragment有自己的生命週期,必須依附Activity。
Fragment載入到Activity的兩種方式
1.靜態載入,在佈局中載入
2.動態載入,在程式碼中載入(用的較多)
fragment經常和viewpager一起使用,不可避免的我們就會接觸到FragmentPagerAdapter和FragmentStatePagerAdapter。
FragmentPagerAdapter和FragmentStatePagerAdapter有什麼區別呢?
FragmentStatePagerAdapter在切換的時候會回收fragment
而FragmentPagerAdapter在切換時會將fragment與viewPager分離,並儲存fragment的ui資訊,
相比之下FragmentStatePagerAdapter更節省記憶體。所以在,在fragment比較多的時候推薦使用FragmentStatePagerAdapter。
Fragment的生命週期
Fragment是必須依附於Activity的,因此Activity的生命週期會直接影響到Fragment的生命週期。
詳細的生命週期我們來看下面這張圖:
由圖片我們可以看整個fragment和Activity的生命週期執行順序
fragment從建立到建立完成:
1.呼叫fragment中的onAttach() fragment與Activity發生關聯時呼叫
2.呼叫fragment中的onCreate() 建立fragment時呼叫
3.呼叫fragment中的onCreateView() 繪製fragment檢視時呼叫
4.呼叫fragment中的onViewCreated() 介面繪製完成後呼叫
5.呼叫activity中的onCreate() activity建立了
6.呼叫fragment中的onActivityCreated() 在activity的onCreate()方法之後呼叫,表明activity已經繪製完成
7.呼叫activity中的onstart() 表明activity可見了
8.呼叫fragment中的onstart() activity可見後呼叫fragment中的onstart(),表明fragment也可見了
9.呼叫activity的onresume()方法 表明activity可以跟使用者互動了
10.呼叫fragment的onResume()方法 此時,fragment也可以與使用者進行互動了,到此為止,fragment完全初始化完畢了。
fragment的銷燬過程:
1.呼叫fragment中的onPause() 此時fragment不可與使用者互動
2.呼叫activity中的onPause() 此時activity不可與使用者互動
3.呼叫fragment中的onStop() 此時fragment不可見
4.呼叫activity中的onStop() 此時activity不可見
5.呼叫fragment中的onDestoryView() fragment檢視被移除呼叫
6.呼叫fragment中的onDestory() fragment銷燬時呼叫
7.呼叫fragment中的onDetach() fragment與activity解除關聯時呼叫
8.呼叫activity中的ondDestory() activity銷燬
fragment通訊
1.fragment呼叫Activity中的方法
通過getActivity()呼叫
2.在Activity中呼叫Fragment中的方法
需要在fragment類中定義一個介面並在Activity中實現它。Fragment在onAttach()回撥函式中獲取介面的具體實現的物件。然後,fragment就可以呼叫介面中的方法實現與Activity的通訊。
3.在Fragment中調Fragment中的方法
通過getSupportFragmentManager().findFragmentById()
FragmentManager中的add,remove和replace
一般我們兩種模式,一種是將fragment新增(add)到容器中,控制其隱藏和顯示。這種模式不會銷燬fragment。
另一種就是替換(replace)這種方法會把之前的fragment銷燬掉。
Service相關
service是四大元件之一,用的地方也很多。可以在後臺執行一些邏輯。
什麼是Service
Service是一種能在後臺執行耗時任務的沒有介面顯示的元件。需要注意的是Service和BroadCastReceiver都是執行在主執行緒的,所以,Service本身不能做耗時操作,而是通過子執行緒去完成!
Service和Thread的區別
詳細可以看這篇部落格service和thread的區別
講的非常仔細。
在這裡做個總結:
Thread和Service實際上是沒有任何關係,只不過因為字面上的意思,我們可能會誤解為Service可以執行耗時任務的,實際上Service是執行在主執行緒上的,也就是說,Service本身並不能做耗時操作,一般都是在Service中啟執行緒去執行耗時任務。
Thread是程式執行的最小單元,是獨立與Activity執行的,也就是說,如果我們在Activity中啟執行緒去執行任務,即使這個activity被銷燬了,該任務也會繼續執行。
而Service是Android中一種機制,在一些執行在後臺的不需要介面的地方可以使用Service。
Service的生命週期
onbind/onCreate/onStartCommand/ondestory
onBind(): 該方法返回的是一個IBinder介面,當我們使用bindService的時候才會被呼叫
onCreate(): 服務首次建立時呼叫,注意,只有service第一個被建立時才會呼叫
onStartCommand(): 每次呼叫startService的時候都會執行該方法,該方法有一個int型別的返回值
分別是:START_STICKY、START_NOT_STICKY、START_REDELIVER_INTENT、START_STICKY_COMPATIBILITY。
START_STICKY:”粘性的”,如果service程序被意外kill掉,保留service的狀態為開始狀態,但不保留遞送的intent物件。隨後系統會嘗試重新建立service,由於服務狀態為開始狀態,所以建立服務後一定會呼叫onStartCommand(Intent,int,int)方法。如果在此期間沒有任何啟動命令被傳遞到service,那麼引數Intent將為null。
START_NOT_STICKY:“非粘性的”。使用這個返回值時,如果在執行完onStartCommand後,服務被異常kill掉,系統不會自動重啟該服務
START_REDELIVER_INTENT:重傳Intent。使用這個返回值時,如果在執行完onStartCommand後,服務被異常kill掉,系統會自動重啟該服務,並將Intent的值傳入。
START_STICKY_COMPATIBILITY:START_STICKY的相容版本,但不保證服務被kill後一定能重啟。
onDestory(): 服務銷燬時呼叫,在這裡可以做一些資源回收操作。
Service的兩種啟動方式
startService 和 bindService
startService
1.定義一個類繼承自Service
2.在清單配置檔案中宣告
3.使用Context.startService(Intent)啟動Service
4.呼叫Context.stopService(Intent)停止Service
Intent intent = new Intent();
intent.setClass(activity, UpdateApkService.class);
activity.startService(intent);//開啟服務
執行startService時,Service會經歷onCreate->onStartCommand。當執行stopService時,直接呼叫onDestroy方法。呼叫者如果沒有stopService,那麼即使Activity被銷燬了,Service也會繼續執行,下次呼叫者再起來仍然可以stopService。
bindService
1.建立一個類繼承自Service,並在類中建立一個實現IBinder介面的例項物件並提供公共方法。
/*這裡定義一個類 用於返回Service*/
public class MyBinder extends Binder {
public MyService getService() {
return MyService.this;
}
}
/*提供一個公共方法*/
public Date getTime(){
return new Date();
}
2.在onBind()中返回自定義的IBinder例項
private MyBinder myBinder=new MyBinder();
@Override
public IBinder onBind(Intent intent) {
return myBinder;
}
3.在需要呼叫的地方,從onServiceConnected中獲取IBinder例項並呼叫公共方法
sc = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i("aaa","onServiceConnected");
MyService.MyBinder myBinder = (MyService.MyBinder) service;
Date date = ((MyService.MyBinder) service).getService().getTime();
Log.i("aaa",date.toString());
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
Intent intent = new Intent(this, MyService.class);
bindService(intent, sc, BIND_AUTO_CREATE);
執行bindService時,Service會經歷onCreate->onBind。這個時候呼叫者和Service繫結在一起。呼叫者呼叫unbindService方法或者呼叫者Context不存在了(如Activity被finish了),Service就會呼叫onUnbind->onDestroy。這裡所謂的繫結在一起就是說兩者共存亡了。
BroadcastReceiver
四大元件之一,在Android中,Broadcast是一種廣泛運用在應用程式之間傳輸資訊的機制,Android中我們要傳送的是一個intent,intent可易攜帶我們需要傳輸的資料。
廣播的使用場景
1.同一app中不同元件之間的資料傳遞
2.不同app之間元件的資料傳遞
廣播的種類
1.普通廣播 Context.sendBroadcast
2.有序廣播 Context.sendOrderedBroadcast 根據優先順序傳播,優先順序高的接收器和一阻止繼續傳播活修改資料
3.本地廣播 LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this); lbm.sendBroadcast(new Intent(LOCAL_ACTION)); 只會在應用內部傳播,相對來說資料安全。
廣播的註冊方式
1.靜態註冊 在清單配置檔案中宣告,即使程序被殺死,該廣播仍然執行
<receiver android:name=".MyReceiver">
<intent-filter>
<action android:name="android.intent.action.MY_BROADCAST"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
2.動態註冊 在程式碼中註冊,受activity生命週期的影響。
MyReceiver receiver = new MyReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.MY_BROADCAST");
registerReceiver(receiver, filter);
內部實現機制
1.自定義BroadcastReceiver,重寫onReceive()方法
2.通過Binder機制向AMS(Activity Manager Service)進行註冊
3.廣播發送者通過Binder機制向AMS傳送廣播
4.AMS查詢符合相應條件(IntentFilter/Permission等)的BroadcastReceiver,將廣播發送到BroadCastReceiver相應的訊息迴圈佇列中
5.訊息迴圈執行拿到廣播,回撥BroadCastReceiver中的onReceive()方法。
LocalBroadcastManager
1.使用LocalBroadcastManager傳送的廣播只能在app內部傳播,因此資料傳輸很安全。
2.比系統廣播更加高效,底層是通過Handler傳送message實現的。