1.Activity系列
1.1 Activity的生命週期
activity的生命週期方法爲onCreate()、onStart()、onResume()、onPause()、onStop()、onDestroy()、後面再加一個再次啓動時的onRestart();
- 打開A Activity,分別執行onCreate()、onStart()、onResume()
- 從A Activity打開B Activity,分別執行A onPause(), B onCreate(),B onStart(),B onResume(),A onStop()
- 關閉B Activity,分別執行B onPause(),A onRestart(),A start(),A resume(),B onStop(), B on Destroy()
- 將A Activity由豎屏切換爲橫屏,如果清單文件中沒有設置android:configChanges屬性,則先銷燬再創建,即 onPause(),onStop(),onDestroy(),onCreate(),onStart(),onResume(),設置了orientation|screenSize(一定要同時出現)屬性值之後,不再走生命週期方法,直接調用onConfigrationChanged()方法。
- Activity切換中onPause()和onStop()方法比較特殊,在onPause()方法中中不要加入太多耗時的操作,會影響用戶體驗,
1.2 Activity的啓動模式
task:翻譯過來就是‘任務’,是一組相互有關聯的activity的集合,可以理解爲activity是在task裏面活動的,task存在於一個叫back stack的數據結構中的,他是以棧的方式去管理activity的,因此也被稱爲任務棧。
taskAffinity:taskAffinity可以翻譯爲activity相關或關聯的任務,這個參數標記了這個activity所需要任務棧的名字,默認情況下,activity相關任務棧的名字是應用程序的包名。taskAffinity與singleTask模屬性啓動模式或者allowTaskReparenting屬性配對使用。
4種啓動模式:
standard:標準模式,在A Activity中啓動B Activity,不管A Activity所在的棧中是否含有B Activity的實例,都會new 一個B Activity的實例放在A所在棧的棧頂。非Activity的Context啓動standard模式(如ApplicationContext)會報錯。
singleTop:棧頂複用模式,在A Activity中啓動B Activity,查看A所在的任務棧棧頂是否是B Activity的實例,如果是,則不需要new B Activity的實例而是直接引用棧頂的實例,並且回調onNewIntent()方法,通過該方法的參數可以取得請求的信息。如果不是,會再new 一個B Activity的實例,而會使用這個棧頂的B Activity。
singleTask:棧內複用模式,啓動一個Activity,先從系統中查找與activity的taskAffinity屬性相匹配的任務棧是否存在,如果不存在,創建棧,然後new Activity的實例放入棧中,如果存在,則在棧中尋找該實例,如果該實例存在,銷燬棧中該activity 上面的所有activity,最終讓該activity位於棧頂。如果實例不存在,則直接創建一個實例並壓入棧頂。
singleInstance:單實例模式,是SingleTask的加強版,除了singleTask的功能外,此模式的Activity必須單獨地位於一個任務棧,不與其他Activity位於同一棧內。
1.3 onCreate與onSaveInstanceState與onRestoreInstanceState
1)、onCreate(Bundle savedInstanceState) 方法
Activity 創建時回調 : 該方法會自動傳入一個 Bundle 對象, 該 Bundle 對象就是上次被系統銷燬時在 onSaveInstanceState 或者 onRestoreInstanceState 中保存的數據
-- 注意 : 只有是系統自動回收的時候纔會保存 Bundle 對象數據;
-- Bundle 對象來源 : onCreate() 方法中的 Bundle 對象參數, 是在 onSaveInstance() 或者 onRestoreInstanceState() 方法中保存的 Bundle 對象;
2)、 onSaveInstanceState(Bundle outState) 方法
onSaveInstanceState函數是Activity的生命週期函數
outState 參數作用 :
數據保存 : Activity 生命週期結束的時候, 需要保存 Activity 狀態的時候, 會將要保存的數據使用鍵值對的形式 保存在 Bundle 對象中;
恢復數據 : 在 Activity 的 onCreate()方法 創建 Activity 的時候會傳入一個 Bundle 對象, 這個 Bundle 對象就是這個 outState 參數;
調用時機 : Activity 容易被銷燬的時候調用, 注意是容易被銷燬, 也可能沒有銷燬就調用了;
按下Home鍵 : Activity 進入了後臺, 此時會調用該方法;
按下電源鍵 : 屏幕關閉, Activity 進入後臺;
啓動其它 Activity : Activity 被壓入了任務棧的棧底;
橫豎屏切換 : 會銷燬當前 Activity 並重新創建;
onSaveInstanceState方法調用注意事項 :
用戶主動銷燬不會調用 : 當用戶點擊回退鍵 或者 調用了 finish() 方法, 不會調用該方法;
調用時機不固定 : 該方法一定是在 onStop() 方法之前調用, 但是不確定是在 onPause() 方法之前 還是 之後調用;
佈局中組件狀態存儲 : 每個組件都 實現了 onSaveInstance() 方法, 在調用函數的時候, 會自動保存組件的狀態, 注意, 只有有 id 的組件纔會保存;
關於默認的 super.onSaveInstanceState(outState) : 該默認的方法是實現 組件狀態保存的;
(3) onRestoreInstanceState(Bundle savedInstanceState) 方法
方法回調時機 : 在 Activity 被系統銷燬之後 恢復 Activity 時被調用, 只有銷燬了之後重建的時候才調用, 如果內存充足, 系統沒有銷燬這個 Activity, 就不需要調用;
-- Bundle 對象傳遞 : 該方法保存的 Bundle 對象在 Activity 恢復的時候也會通過參數傳遞到 onCreate() 方法中;
——————————————————————————————————————————————————————
2.Service系列
2.1 Service的生命週期
Service的生命週期方法有以下幾種:
4個手動調用的方法:
- startService()
- stopService()
- bindService()
- unbindService();
5個內部調用的方法:
- onCreate() //創建服務
- onStartCommand() //開啓服務
- onDestroy() //停止服務
- onBind() //綁定服務
- onUnbind() //解除綁定
- 手動調用startService()方法,內部執行onCreate()、onStartCommand()方法,如果一個Service被startService()了多次,但是隻會onCreate()一次。
- 手動調用stopService()方法,內部執行onDestroy()方法,但是如果Service已經綁定,則無法停止服務除非已經解綁
- 手動調用bindService()方法,內部執行onCreate(),onBind()方法
- 手動調用unvindService()方法,內部執行onUnbind(),onDestroy()方法
- startService()和stopService()只能開啓和停止Service,但是不能操作Service,所以服務還在。而bindService()和unbindService()可以操作Service,調用者退出後,Service會隨着銷燬。
2.2 Service的缺點
默認情況下, 是在main Thread中進行的,所以一般進行復雜的操作需要開啓新的線程。一般在onStartCommand()中可以執行一些輕量的網絡操作。
- Service不會專門啓動一條單獨的進程,它與所在的應用程序處於同一進程。
- Service也不是專門一條新的線程,因此不應該在Service中直接進行耗時的操作(可以開啓一條新的線程)
2.3 IntentService————(因Service的缺點而產生)
特徵:
-
- 會創建獨立的Worker線程來處理所有的Intent請求。
- 會創建獨立的Worker線程來處理onHandlerIntent()實現的代碼,不需要處理多線程問題。
- 所有的請求完成後,IntentService自動停止,不需要調用stopSelf()來停止Service;
- 爲Service的onBind()提供默認實現,返回null;
- 爲Service的onStartCommand()提供默認實現,將Intent請求添加到隊列中。
讓Service類繼承IntentService,重寫onStartCommand()與onHandlerIntent()方法。
啓動Service的方式有兩種,根據action獲取Service時應該設置好包名;
————————————————————————————————————————————————————————
3. BroadCastReceiver
3.1 Android引入廣播機制的意義
爲了方便四大組件之間數據與信息的交互。
程序間互通消息(如監聽系統來電)
效率上(如UDP的廣播協議在局域網上的方便性)
設計模式上(反轉控制的一種應用,類似於監聽者模式)
3.2 廣播註冊
首先寫一個類繼承BroadCastReceiver;
靜態註冊
<receiver>
<intent-filter>
<action name="android.provider.Telephony.SMS_RECEIVED"/>
</intent/filter>
</receiver>
動態註冊
IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
MyBroadCastReceiver myreceiver = new MyBroadCastReceiver();
registerReceiver(myreciver.filter);
兩種方式的比較:
- 靜態註冊:常駐型廣播,程序關閉也能收到短信,程序會被系統自動調用
- 動態註冊:非常駐型廣播,也就是說廣播跟着程序的生命週期。
發送廣播的兩種方式:
- 同步廣播:Context.sendBrodcast()
- 有序廣播:Context.sendOrderedBrodcast()
3.3 廣播接收者的生命週期
- 廣播接收者的生命週期非常的短,當調用onRecieve()方法後,廣播就會銷燬
- 在廣播接收中不能進行耗時的操作
- 在廣播接收者不能創建子線程。廣播接收者完成操作後,所在的進程會變爲空進程,很容易被系統回收。
————————————————————————————————————————————————————————
4.ContentProvider
4.1ContentProvider的作用
ContentProvider用於提供第三方應用數據的訪問方案,可以派生ContentProvider類,對外提供接口。
4.2ContentProvider、ContentResolve、ContentObserver之間的關係
ContentProvider:內容提供者,對外提供數據內容,contentprovider.notifyChanges(uri)更新提供內容。
ContentResolver:內容解析者,解析ContentProvider提供的內容。
ContentObserver:內容監聽者,監聽數據的變化,contentObserver.registerContentObserver()
————————————————————————————————————————————————
5.四大組件之間的交互
activity之間的交互:使用Intent傳遞數據,startActivity(Intent intent)
activity與service之間的交互:使用Intent傳遞數據,startService(Intent intent)
activity與BroadcastReceiver之間的交互:使用Intent傳遞數據,sendBroadcast(Intent intent)