目錄
一.Activity詳解
問:什么是Activity
答:Android 是與用戶交互的接口油猫,它提供了一個界面讓用戶進行點擊和各種滑動操作岛请,這就是Activity的意義剩辟。
一.Activity的生命周期
1.activity的四種狀態(tài)
1.1 running狀態(tài)(運行):表明activity是處于活動狀態(tài)眠冈,這時候用戶可以點擊屏幕,屏幕會做出相應缎讼,它是一個activity處于棧頂?shù)囊粋€狀態(tài)收夸。
1.2 paused狀態(tài)(暫停):表明activity失去焦點的時候(失去焦點但仍然對用戶可見),或者是被一個非全屏的activity占據(jù)血崭,或者是被一個透明的activity放置在棧頂卧惜,會處于paused狀態(tài),但是我們需要明白這個時候activity只是失去了和用戶的交互能力夹纫,用戶對這個屏幕操作是沒有反應的咽瓷,并不是說整個activity被銷毀,這時候它所有的狀態(tài)信息和成員變量都還在舰讹,當然有一種情況就是內存緊張的時候茅姜,這個activity會被回收。
1.3 stopped狀態(tài)(停止):當這個activity被另外一個activity完全覆蓋時候月匣,被覆蓋的那個activity就會處于stopped狀態(tài)钻洒,這時候它不再是可見的,但是它跟paused狀態(tài)一樣桶错,在內存不緊張的情況航唆,它的一些內存信息和成員變量都還在。
1.4 killed狀態(tài)(銷毀):表明activity已經(jīng)被系統(tǒng)回收掉了院刁,這時候它保存的信息糯钙,成員變量都不在了。
2.activty生命周期分析
靈活的記憶activity的生命周期:
2.1 Activity啟動
onCreate() -> onStart() -> onResume()
onCreate():是在Activity被創(chuàng)建的時候回調。
onStart():表明Activity正在啟動任岸,Activity已經(jīng)處于用戶可見的狀態(tài)再榄,并沒有處于前臺顯示,用戶還不能與這個Activity進行交互享潜,就是用戶看見了但是還不能點擊的狀態(tài)困鸥。
onResume():在前臺可見了,已經(jīng)可以與用戶交互了剑按,能進行點擊疾就,觸摸,滑動等等艺蝴。 在onResume中可以初始化一些資源猬腰。
2.2 HOME鍵
Home鍵退出:onPause() -> onStop()
onPause():這個方法被調用時,說明整個Activity是處于paused(暫停)狀態(tài)的猜敢」煤桑可見的但是不能被觸摸的狀態(tài),當用戶退出至后臺時onPause方法就會被調用缩擂。
onStop():一般都會在onPause方法執(zhí)行后執(zhí)行鼠冕。表明Activity被停止,或者被完全覆蓋胯盯,這時候Activity是完全不可見的懈费。這時候如果內存緊張的話就有可能會被回收掉。
Home鍵回來:onRestart() -> onStart() -> onResume()
onRestart(): 表示Activity重新啟動陨闹,Activity由不可見狀態(tài)到可見狀態(tài)的時候楞捂。 應用場景(用戶打開了一個新Activity薄坏,當前Activity就會被占據(jù)趋厉,又回到這個Activity時就會調用onRestart()方法)
2.3 BACK鍵
onPause() -> onStop() -> onDestroy()
onDestroy():表明當前Activity正在被銷毀,生命周期最后一個方法胶坠,在這個生命周期方法中我們可以做一些回收工作君账,以及一些資源的釋放。
3.android 進程優(yōu)先級(參考文章)
當系統(tǒng)的內存不足時, android系統(tǒng)將根據(jù)進程優(yōu)先級選擇殺死一些不太重要的進程. 進程優(yōu)先級從高到低分別為:
前臺進程/可見進程/服務進程/后臺進程/空進程
前臺進程:(重點為a沈善,b兩點)
a. 進程中包含處于前臺的正與用戶交互的activity;
b. 進程中包含與前臺activity綁定的service;
c. 進程中包含調用了startForeground()方法的service;
d. 進程中包含正在執(zhí)行onCreate(), onStart(), 或onDestroy()方法的service;
e. 進程中包含正在執(zhí)行onReceive()方法的BroadcastReceiver.
系統(tǒng)中前臺進程的數(shù)量很少, 前臺進程幾乎不會被殺死. 只有當內存低到無法保證所有的前臺進程同時運行時才會選擇殺死某個前臺進程.
可視進程:
a. 進程中包含未處于前臺但仍然可見的activity(調用了activity的onPause()方法, 但沒有調用onStop()方法). 典型的情況是運行activity時彈出對話框, 此時的activity雖然不是前臺activity, 但其仍然可見.
b. 進程中包含與可見activity綁定的service.
可視進程不會被系統(tǒng)殺死, 除非為了保證前臺進程的運行而不得已為之.
服務進程 進程中包含已啟動的service.
后臺進程 進程中包含不可見的activity(onStop()方法調用后的activity). 后臺進程不會直接影響用戶體驗, 為了保證前臺進程/可視進程/服務進程的運行, 系統(tǒng)隨時都有可能殺死一個后臺進程. 一個正確的實現(xiàn)了生命周期方法的activity處于后臺時被系統(tǒng)殺死, 可以在用戶重新啟動它時恢復之前的運行狀態(tài).(例如在點擊home鍵后乡数,前臺進程就變成了后臺進程,如果內存緊張的情況下就會被咔嚓掉)
空進程 不包含任何處于活動狀態(tài)的進程是一個空進程. 系統(tǒng)經(jīng)常殺死空進程, 這不會造成任何影響. 空進程存在的唯一理由是為了緩存一些啟動數(shù)據(jù), 以便下次可以更快的啟動.(只要不屬于前面4種闻牡,都是空進程净赴,沒有回掉的組件,出于緩存的目的而保留)
二.Android的任務棧
android 的內部是一個棧結構罩润,棧結構就是后進先出的概念玖翅,用這個棧來存儲Activity,每次打開一個新activity或者退出當前activity時,都會在一個任務棧當中添加或刪除一個activity組件金度,因此一個task包含了其實是一個activity集合,android 的系統(tǒng)通過任務棧(返回棧)來有序的管理每一個Activity应媚。在android 當中,退出應用程序的時候猜极,必須要把任務當中的所有Activity清除出棧中姜,這時候,才能安全的跟伏,完全的退出程序丢胚。任務棧只有被銷毀了才是處于數(shù)據(jù)最安全的狀態(tài),當然如果不去刪除它的話受扳,一定要合理的去保存這個任務棧嗜桌。這時候它這個任務棧就保留了每個activity的狀態(tài)也會保存activity的信息,但是特別要注意的是一定要安全的保存任務棧辞色,任務棧并不是唯一的骨宠,某些情況下一個activity可以獨享一個任務棧,這就是啟動模式當中 的 singleInstance相满。如果想更詳細的了解的話层亿,可以去看郭霖大神的Android任務和返回棧完全解析,細數(shù)那些你所不知道的細節(jié)立美。
三.Activity啟動模式
1.standard(默認啟動模式)
在這種模式下匿又,每次啟動一個activity都會重新創(chuàng)建一個activity實例,然后將它加到任務棧當中建蹄,就是task當中碌更,不會考慮這個task當中有沒有這個實例,不會去復用這個activity洞慎,只會重新創(chuàng)建activity痛单,在這個模式當中,每次創(chuàng)建一個activity劲腿,都會走相應的生命周期方法旭绒,是非常消耗資源的。
為什么android 會提供一個啟動模式焦人,在開發(fā)中一般都會在不同頁面間跳轉挥吵,不同頁面跳轉實質就是activity 間的跳轉。我們肯定會復用某個activity 花椭。如果跳轉到某個原來的activity實例的時候忽匈,希望activity是復用的,而不是重新創(chuàng)建的矿辽,重新創(chuàng)建是非常消耗資源的丹允,如果每一次創(chuàng)建一個activity都放在task當中歪沃,就像standard模式一樣。對內存嫌松,系統(tǒng)都是一個很大的消耗沪曙。
android 提供了第二種啟動模式
2.singletop (棧頂復用模式)
如果你創(chuàng)建的activity是在任務棧的棧頂,它就不會創(chuàng)建新的activity萎羔,而是復用棧中的activity液走,如果你創(chuàng)建的activity 不是在棧頂,它還是會創(chuàng)建activity的贾陷。
所以為了提高復用模式缘眶,android又提供了第三種啟動模式
3.singletask(棧內復用模式)
它其實是一個單例模式,每一次啟動activity時髓废,系統(tǒng)會在任務棧中檢查是否存在該活動的實例巷懈,如果存在就直接將activity置于棧頂。注意慌洪,它把activity置于棧頂顶燕,把這個activity以上的activity都從任務棧中移除,銷毀(在任務棧里面只允許一個實例)冈爹。
4.singleinstance(單實例模式)
這個模式比較特殊涌攻,這個activity在整個系統(tǒng)當中有且只有一個實例,而且這個activity獨享任務棧频伤。(例如 SecondActivity設置成singleinstance模式恳谎。讓FirstActivity跳轉到了 SecondActivity,SecondActivity跳轉 ThirdActivity憋肖,然后back 因痛,會發(fā)現(xiàn),ThirdActivity直接回到了FirstActivity再按back岸更,才到SecondActivity鸵膏,因為FirstActivity和ThirdActivity是同一個棧的,這個棧退出空了坐慰,就會顯示另一個任務棧(返回棧)的棧頂活動)
假設我們的程序中有一個活動是允許其他程序調用的较性,如果我們想實現(xiàn)其他程序和我們的程序可以共享這個活動的實例用僧,應該如何實現(xiàn)呢结胀?使用前面3種啟動模式肯定是做不到的,因為每個應用程序都會有自己的返回棧责循,同一個活動在不同的返回棧中入棧時必然是創(chuàng)建了新的實例糟港。而是用singleInstance模式就可以解決這個問題,在這種模式下會有一個單獨的返回棧來管理這個活動院仿,不管是哪個應用程序來訪問這個活動秸抚,都共用的同一個返回棧速和,也就解決了共享活動實例的問題。 選自《第一行代碼》
四.scheme跳轉協(xié)議
android中的scheme是一種頁面內跳轉協(xié)議剥汤,是一種非常好的實現(xiàn)機制颠放,通過定義自己的scheme協(xié)議,可以非常方便跳轉app中的各個頁面吭敢;通過scheme協(xié)議碰凶,服務器可以定制化告訴App跳轉那個頁面,可以通過通知欄消息定制化跳轉頁面鹿驼,可以通過H5頁面跳轉頁面等欲低。
操作方法很簡單,客戶端向H5頁面注冊一個URL Scheme畜晰,由Scheme協(xié)議從瀏覽器中啟動這個Activity砾莱。Scheme應用場景:
1.服務端下發(fā)一個URL的路徑然后客戶端根據(jù)服務端下發(fā)的URL跳轉到相應的頁面。
2.從H5頁面跳轉到相應的APP Activity
3.APP根據(jù)URL跳轉到另一個APP的指定頁面
scheme跳轉協(xié)議在開發(fā)中是極其重要的凄鼻】岩常可以看這篇文章詳細了解下android H5 應用內跳轉Scheme協(xié)議