極力推薦文章:歡迎收藏
Android 乾貨分享 android
用戶可操做的可視化界面,爲用戶提供一個完成操做指令的窗口。一個Activity
一般是一個單獨的屏幕,Activity
經過Intent
來進行通訊。Android
中會維持一個Activity Stack
,當一個新Activity
建立時,它就會放到棧頂,這個Activity
就處於運行狀態。程序員
服務,運行在手機後臺,適合執行不需和用戶交互且還需長期運行的任務。數據庫
內容提供者,使一個應用程序的指定數據集提供給其餘應用程序,其餘應用可經過ContentResolver
類從該內容提供者中獲取或存入數據。它提供了一種跨進程數據共享的方式,當數據被修改後,ContentResolver
接口的notifyChange
函數通知那些註冊監控特定URI
的ContentObserver
對象。瀏覽器
若是ContentProvider
和調用者在同一進程中,ContentProvider
的方法(query/insert/update/delete等)
和調用者在同一線程中;若是ContentProvider
和調用者不在同一進程,ContentProvider
方法會運行在它自身進程的一個Binder
線程中。安全
廣播接收者,運用在應用程序間傳輸信息,可使用廣播接收器來讓應用對一個外部事件作出響應。微信
onCreate()->onStart()->onResume()->onPause()->onStop()->onDestory()
網絡
爲Activity
設置佈局,此時界面還不可見;框架
Activity
可見但還不能與用戶交互,不能得到焦點異步
從新啓動Activity
時被回調ide
Activity
可見且可與用戶進行交互
當前Activity
暫停,不可與用戶交互,但還可見。在新Activity
啓動前被系統調用保存現有的Activity
中的持久數據.中止動畫等。
當Activity
被新的Activity
覆蓋不可見時被系統調用
當Activity
被系統銷燬殺掉或是因爲內存不足時調用
bind
服務的生命週期以下:
onCreate->onBind->onUnBind->onDestory
無論調用bindService
幾回,onCreate
只會調用一次,onStart
不會被調用,創建鏈接後,service
會一直運行,直到調用unBindService
或是以前調用的bindService
的Context
不存在了,系統會自動中止Service
,對應的onDestory
會被調用。
啓動Service
的聲明週期以下:
onCreate->onStartCommand->onDestory
start
屢次,onCreate
只會被調用一次,onStart
會調用屢次,該service
會在後臺運行,直至被調用stopService
或是stopSelf
。
無論如何調用,onCreate()
只被調用一次,startService
調用多少次,onStart
就會被調用多少次,而unbindService
不會中止服務,必須調用stopService
或是stopSelf
來中止服務。必須unbindService
和stopService(stopSelf)
同時都調用了纔會中止服務。
存活週期是在Context.registerReceiver
和Context.unregisterReceiver
之間,BroadcastReceiver
每次收到廣播都是使用註冊傳入的對象處理的。
進程在的狀況下,receiver
會正常收到廣播,調用onReceive
方法;生命週期只存活在onReceive
函數中,此方法結束,BroadcastReceiver
就銷燬了。onReceive()
只有十幾秒存活時間,在onReceive()
內操做超過10S
,就會報ANR
。
進程不存在的狀況,廣播相應的進程會被拉活,Application.onCreate
會被調用,再調用onReceive
。
和應用的生命週期同樣,它屬於系統應用,應用啓動時,它會跟着初始化,應用關閉或被殺,它會跟着結束。
1.經過Intent
方式傳遞參數跳轉
2.經過廣播方式
3.經過接口回調方式
4.藉助類的靜態變量或全局變量
5.藉助SharedPreference
或是外部存儲,如數據庫或本地文件
Activity(A->B)
切換(B正常的Activity)
的生命週期: onPause(A)->onCreate(B)->onStart(B)->onResume(B)->onStop(A)
這時若是按回退鍵回退到A
onPause(B)->onRestart(A)->onStart(A)->onResume(A)->onStop(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)->onStop(B)->onDestory(B)
Activity(A)
啓動後點擊Home
鍵再回到應用的生命週期: onPause(A)->onStop(A)->onRestart(A)->onStart(A)->onResume(A)
onSaveInstanceState->onPause->onStop->onDestory->onCreate->onStart->onRestoreInstanceState->onResume
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
onAttach->onCreate->onCreateView->onActivityCreated->onStart->onResume->onPause->onStop->onDestoryView->onDestory->onDetach
onAttach->onCreate->onCreateView->onActivityCreated->onStart->onResume
onPause->onSaveInstanceState->onStop
onStart->onRestoreInstanceState->onResume
Fragment:
onPause->onStop->onDestoryView
Fragment:
onCreateView->onActivityCreated->onStart->onResume
onPause->onStop->onDestoryView->onDestory->onDetach
AlertDialog
並不會影響Activity
的生命週期,按Home
鍵後纔會使Activity
走onPause->onStop
,AlertDialog
只是一個組件,並不會使Activity
進入後臺。
前一個Activity
的onPause
,後一個Activity
的onResume
。
會執行onPause->onStop
,再回到前臺,會執行onRestart->onStart->onResume
並不會影響Activity
生命週期
每啓動一次Activity
,都會建立一個實例,即便從ActivityA startActivity ActivityA
,也會再次建立A
的實例放於棧頂,當回退時,回到上一個ActivityA
的實例。
每次啓動Activity
,若是待啓動的Activity
位於棧頂,則不會從新建立Activity
的實例,即不會走onCreate->onStart
,會直接進入Activity
的onPause->onNewIntent->onResume
方法
整個手機操做系統裏只有一個該Activity
實例存在,沒有其餘Actvity
,後續請求均不會建立新的Activity
。若task
中存在實例,執行實例的onNewIntent()
。應用場景:鬧鐘
、瀏覽器
、電話
。
啓動的Activity若是在指定的
taskAffinity的
task棧中存在相應的實例,則會把它上面的
Activity都出棧,直到當前
Activity實例位於棧頂,執行相應的
onNewIntent()方法。若是指定的
task不存在,建立指定的
taskAffinity的
task,taskAffinity的做用,進入指寫
taskAffinity的
task,若是指定的
task存在,將
task移到前臺,若是指定的
task不存在,建立指定的
taskAffinity的
task`. 應用場景:應用的主頁面
Activity
被主動回收時,如按下Back
鍵,系統不會保存它的狀態,只有被動回收時,雖然這個Activity
實例已被銷燬,但系統在新建一個Activity
實例時,會帶上先前被回收Activity
的信息。在當前Activity
被銷燬前調用onSaveInstanceState(onPause和onStop之間保存)
,從新建立Activity
後會在onCreate
後調用onRestoreInstanceState(onStart和onResume之間被調用)
,它們的參數Bundle
用來數據保存和讀取的。
View
狀態有兩個前提: 1.View
的子類必須實現了onSaveInstanceState
;
2.必需要設定Id
,這個ID
做爲Bundle
的Key
;
正常狀況下的生命週期:
onAttach->onCreate->onCreateView->onActivityCreated->onStart->onResume->onPause->onStop->onDestoryView->onDestory->onDetach
onPause(舊)->onAttach->onCreate->onCreateView->onActivityCreated->onStart->onResume->onStop(舊)->onDestoryView(舊)
若是添加到backStack
中,調用remove()
方法fragment
的方法會走到onDestoryView
,但不會執行onDetach()
,即fragment
自己的實例是存在的,成員變量也存在,可是view
被銷燬了。若是新替換的Fragment
已在BackStack
中,則不會執行onAttach->onCreate
。
在對應的Fragment
的Activity.onSaveInstanceState
方法會調用FragmentController.saveAllState
,其中會對mActive
中各個Fragment
的實例狀態和View
狀態分別進行保存。當Activity
在作狀態保存和恢復的時候, 在它其中的fragment
天然也須要作狀態保存和恢復.
若是但願在Fragment
的onActivityResult
接收數據,就要調用Fragment.startActivityForResult
, 而不是Fragment.getActivity().startActivityForResult
。Fragment.startActivityForResult->FragmentActivitymHost.HostCallbacks.onStartActivityFromFragment->FragmentActivity.startActivityFromFragment。
若是request=-1
則直接調用FragmentActivity.startActivityForResult,
它會從新計算requestCode
,使其大於0xfffff
。
ViewPager+FragmentPagerAdapter+List<Fragment>
fragment
中編寫方法,在須要回調的fragment
裏獲取對應的Fragment
實例,調用相應的方法; a)在Fragment1
中建立一個接口及接口對應的set
方法;
b)在Fragment1
中調用接口的方法;
c)在Fragment2
中實現該接口;
能夠在ServiceConnection
的onServiceConnected
中獲取到Service
的實例,這樣就能夠調用service
的方法,若是service
想調用activity
的方法,能夠在service
中定義接口類及相應的set
方法,在activity
中實現相應的接口,這樣service
就能夠回調接口;
ContentProvider、ContentResolver、ContentObserver
之間的關係 實現各個應用程序間數據共享,用來提供內容給別的應用操做。如聯繫人應用中就使用了ContentProvider
,能夠在本身應用中讀取和修改聯繫人信息,不過須要獲取相應的權限。它也只是一箇中間件,真正的數據源是文件或SQLite
等。
內容解析者,用於獲取內容提供者提供的數據,經過ContentResolver.notifyChange(uri)
發出消息
內容監聽者,能夠監聽數據的改變狀態,觀察特定Uri
引發的數據庫變化,繼而作一些相應的處理,相似於數據庫中的觸發器,當ContentObserver
所觀察的Uri
發生變化時,便會觸發它。
BroadcastReceiver
是一種全局監聽器,用來實現系統中不一樣組件之間的通訊。有時候也會用來做爲傳輸少許並且發送頻率低的數據,可是若是數據的發送頻率比較高或者數量比較大就不建議用廣播接收者來接收了,由於這樣的效率很很差,由於BroadcastReceiver
接收數據的開銷仍是比較大的。
徹底異步的,能夠在同一時刻(邏輯上)被全部接收者接收到,消息傳遞的效率比較高,而且沒法中斷廣播的傳播。
發送有序廣播後,廣播接收者將按預先聲明的優先級依次接收Broadcast
。優先級高的優先接收到廣播,而在其onReceiver()
執行過程當中,廣播不會傳播到下一個接收者,此時當前的廣播接收者能夠abortBroadcast()
來終止廣播繼續向下傳播,也能夠將intent
中的數據進行修改設置,而後將其傳播到下一個廣播接收者。 sendOrderedBroadcast(intent, null);
//發送有序廣播
sendStickyBroadcast()
來發送該類型的廣播信息,這種的廣播的最大特色是,當粘性廣播發送後,最後的一個粘性廣播會滯留在操做系統中。若是在粘性廣播發送後的一段時間裏,若是有新的符合廣播的動態註冊的廣播接收者註冊,將會收到這個廣播消息,雖然這個廣播是在廣播接收者註冊以前發送的,另一點,對於靜態註冊的廣播接收者來講,這個等同於普通廣播。
在AndroidManifest
中靜態註冊的廣播接收器,通常咱們在收到該消息後,須要作一些相應的動做,而這些動做與當前App
的組件,好比Activity
或者Service
的是否運行無關,好比咱們在集成第三方Push SDK
時,通常都會添加一個靜態註冊的BroadcastReceiver
來監聽Push
消息,當有Push
消息過來時,會在後臺作一些網絡請求或者發送通知等等。
這種主要是在Activity
或者Service
中使用registerReceiver()
動態註冊的廣播接收器,由於當咱們收到一些特定的消息,好比網絡鏈接發生變化時,咱們可能須要在當前Activity
頁面給用戶一些UI
上的提示,或者將Service
中的網絡請求任務暫停。因此這種動態註冊的廣播接收器適合特定組件的特定消息處理。
靜態註冊的廣播接收者就是一個常駐在系統中的全局監聽器,也就是說若是你應用中配置了一個靜態的BroadcastReceiver
,並且你安裝了應用而不管應用是否處於運行狀態,廣播接收者都是已常常駐在系統中了。
<receiver android:name=".MyBroadcastReceiver"> <intent-filter> <action android:name="com.test.intent.mybroadcastreceiver"/> </intent-filter> </receiver>
動態註冊的廣播接收者只有執行了registerReceiver(receiver, filter)
纔會開始監聽廣播消息,並對廣播消息做爲相應的處理。
IntentFilter fiter = new IntentFilter("com.test.intent.mybroadcastreceiver"); MyBroadcastReceiver receiver = new MyBroadcastReceiver(); registerReceiver(receiver, filter); //撤銷廣播接受者的動態註冊 unregisterReceiver(receiver);
僅在本身的應用內發送接收廣播,也就是隻有本身的應用能收到,數據更加安全。廣播只在這個程序裏,並且效率更高。只能動態註冊,在發送和註冊的時候採用LocalBroadcastManager
的sendBroadcast
方法和registerReceiver
方法。
發送的廣播事件可被其餘應用程序獲取,也能響應其餘應用程序發送的廣播事件(能夠經過 exported
是否監聽其餘應用程序發送的廣播 在清單文件中控制) 全局廣播既能夠動態註冊,也能夠靜態註冊。
1.Popupwindow
在顯示以前必定要設置寬高,Dialog
無此限制。
2.Popupwindow
默認不會響應物理鍵盤的back
,除非顯示設置了popup.setFocusable(true);
而在點擊back
的時候,Dialog
會消失。
3.Popupwindow
不會給頁面其餘的部分添加蒙層,而Dialog
會。
4.Popupwindow
沒有標題,Dialog
默認有標題,能夠經過dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
取消標題
5.兩者顯示的時候都要設置Gravity
。若是不設置,Dialog
默認是Gravity.CENTER
。
6.兩者都有默認的背景,均可以經過setBackgroundDrawable(new ColorDrawable(android.R.color.transparent));
去掉。
7.Popupwindow
彈出後,取得了用戶操做的響應處理權限,使得其餘UI控件不被觸發。而AlertDialog
彈出後,點擊背景,AlertDialog
會消失。
不能夠showDialog, startActivity, LayoutInflation
能夠startService\BindService\sendBroadcast\registerBroadcast\load Resource values
而Activity Context
這些操做均可以,即凡是跟UI
相關的,都得用Activity
作爲Context來處理。
一個應用Context
的數量=Activity
數量+Service
數量+1
(Application數量
)
至此,本篇已結束,若有不對的地方,歡迎您的建議與指正。同時期待您的關注,感謝您的閱讀,謝謝!