Android 你需要掌握的知識(shí)(一)

目錄

Activity.png

一.Activity詳解

問:什么是Activity
答:Android 是與用戶交互的接口,它提供了一個(gè)界面讓用戶進(jìn)行點(diǎn)擊和各種滑動(dòng)操作,這就是Activity的意義。

一.Activity的生命周期

1.activity的四種狀態(tài)

1.1 running狀態(tài)(運(yùn)行):表明activity是處于活動(dòng)狀態(tài),這時(shí)候用戶可以點(diǎn)擊屏幕,屏幕會(huì)做出相應(yīng),它是一個(gè)activity處于棧頂?shù)囊粋€(gè)狀態(tài)。

1.2 paused狀態(tài)(暫停):表明activity失去焦點(diǎn)的時(shí)候(失去焦點(diǎn)但仍然對(duì)用戶可見),或者是被一個(gè)非全屏的activity占據(jù),或者是被一個(gè)透明的activity放置在棧頂,會(huì)處于paused狀態(tài),但是我們需要明白這個(gè)時(shí)候activity只是失去了和用戶的交互能力,用戶對(duì)這個(gè)屏幕操作是沒有反應(yīng)的,并不是說整個(gè)activity被銷毀,這時(shí)候它所有的狀態(tài)信息和成員變量都還在,當(dāng)然有一種情況就是內(nèi)存緊張的時(shí)候,這個(gè)activity會(huì)被回收。

1.3 stopped狀態(tài)(停止):當(dāng)這個(gè)activity被另外一個(gè)activity完全覆蓋時(shí)候,被覆蓋的那個(gè)activity就會(huì)處于stopped狀態(tài),這時(shí)候它不再是可見的,但是它跟paused狀態(tài)一樣,在內(nèi)存不緊張的情況,它的一些內(nèi)存信息和成員變量都還在。

1.4 killed狀態(tài)(銷毀):表明activity已經(jīng)被系統(tǒng)回收掉了,這時(shí)候它保存的信息,成員變量都不在了。

2.activty生命周期分析
圖片來源于網(wǎng)絡(luò).png

靈活的記憶activity的生命周期:
2.1 Activity啟動(dòng)
onCreate() -> onStart() -> onResume()

onCreate():是在Activity被創(chuàng)建的時(shí)候回調(diào)。
onStart():表明Activity正在啟動(dòng),Activity已經(jīng)處于用戶可見的狀態(tài),并沒有處于前臺(tái)顯示,用戶還不能與這個(gè)Activity進(jìn)行交互,就是用戶看見了但是還不能點(diǎn)擊的狀態(tài)。
onResume():在前臺(tái)可見了,已經(jīng)可以與用戶交互了,能進(jìn)行點(diǎn)擊,觸摸,滑動(dòng)等等。 在onResume中可以初始化一些資源。

2.2 HOME鍵
Home鍵退出:onPause() -> onStop()

onPause():這個(gè)方法被調(diào)用時(shí),說明整個(gè)Activity是處于paused(暫停)狀態(tài)的。可見的但是不能被觸摸的狀態(tài),當(dāng)用戶退出至后臺(tái)時(shí)onPause方法就會(huì)被調(diào)用。
onStop():一般都會(huì)在onPause方法執(zhí)行后執(zhí)行。表明Activity被停止,或者被完全覆蓋,這時(shí)候Activity是完全不可見的。這時(shí)候如果內(nèi)存緊張的話就有可能會(huì)被回收掉。

Home鍵回來:onRestart() -> onStart() -> onResume()

onRestart(): 表示Activity重新啟動(dòng),Activity由不可見狀態(tài)到可見狀態(tài)的時(shí)候。 應(yīng)用場(chǎng)景(用戶打開了一個(gè)新Activity,當(dāng)前Activity就會(huì)被占據(jù),又回到這個(gè)Activity時(shí)就會(huì)調(diào)用onRestart()方法)

2.3 BACK鍵
onPause() -> onStop() -> onDestroy()

onDestroy():表明當(dāng)前Activity正在被銷毀,生命周期最后一個(gè)方法,在這個(gè)生命周期方法中我們可以做一些回收工作,以及一些資源的釋放。

3.android 進(jìn)程優(yōu)先級(jí)(參考文章

當(dāng)系統(tǒng)的內(nèi)存不足時(shí), android系統(tǒng)將根據(jù)進(jìn)程優(yōu)先級(jí)選擇殺死一些不太重要的進(jìn)程. 進(jìn)程優(yōu)先級(jí)從高到低分別為:
前臺(tái)進(jìn)程/可見進(jìn)程/服務(wù)進(jìn)程/后臺(tái)進(jìn)程/空進(jìn)程

前臺(tái)進(jìn)程:(重點(diǎn)為a,b兩點(diǎn))
a. 進(jìn)程中包含處于前臺(tái)的正與用戶交互的activity;

b. 進(jìn)程中包含與前臺(tái)activity綁定的service;

c. 進(jìn)程中包含調(diào)用了startForeground()方法的service;

d. 進(jìn)程中包含正在執(zhí)行onCreate(), onStart(), 或onDestroy()方法的service;

e. 進(jìn)程中包含正在執(zhí)行onReceive()方法的BroadcastReceiver.

系統(tǒng)中前臺(tái)進(jìn)程的數(shù)量很少, 前臺(tái)進(jìn)程幾乎不會(huì)被殺死. 只有當(dāng)內(nèi)存低到無法保證所有的前臺(tái)進(jìn)程同時(shí)運(yùn)行時(shí)才會(huì)選擇殺死某個(gè)前臺(tái)進(jìn)程.

可視進(jìn)程:

a. 進(jìn)程中包含未處于前臺(tái)但仍然可見的activity(調(diào)用了activity的onPause()方法, 但沒有調(diào)用onStop()方法). 典型的情況是運(yùn)行activity時(shí)彈出對(duì)話框, 此時(shí)的activity雖然不是前臺(tái)activity, 但其仍然可見.

b. 進(jìn)程中包含與可見activity綁定的service.

可視進(jìn)程不會(huì)被系統(tǒng)殺死, 除非為了保證前臺(tái)進(jìn)程的運(yùn)行而不得已為之.

服務(wù)進(jìn)程 進(jìn)程中包含已啟動(dòng)的service.

后臺(tái)進(jìn)程 進(jìn)程中包含不可見的activity(onStop()方法調(diào)用后的activity). 后臺(tái)進(jìn)程不會(huì)直接影響用戶體驗(yàn), 為了保證前臺(tái)進(jìn)程/可視進(jìn)程/服務(wù)進(jìn)程的運(yùn)行, 系統(tǒng)隨時(shí)都有可能殺死一個(gè)后臺(tái)進(jìn)程. 一個(gè)正確的實(shí)現(xiàn)了生命周期方法的activity處于后臺(tái)時(shí)被系統(tǒng)殺死, 可以在用戶重新啟動(dòng)它時(shí)恢復(fù)之前的運(yùn)行狀態(tài).(例如在點(diǎn)擊home鍵后,前臺(tái)進(jìn)程就變成了后臺(tái)進(jìn)程,如果內(nèi)存緊張的情況下就會(huì)被咔嚓掉)

空進(jìn)程 不包含任何處于活動(dòng)狀態(tài)的進(jìn)程是一個(gè)空進(jìn)程. 系統(tǒng)經(jīng)常殺死空進(jìn)程, 這不會(huì)造成任何影響. 空進(jìn)程存在的唯一理由是為了緩存一些啟動(dòng)數(shù)據(jù), 以便下次可以更快的啟動(dòng).(只要不屬于前面4種,都是空進(jìn)程,沒有回掉的組件,出于緩存的目的而保留)

二.Android的任務(wù)棧

android 的內(nèi)部是一個(gè)棧結(jié)構(gòu),棧結(jié)構(gòu)就是后進(jìn)先出的概念,用這個(gè)棧來存儲(chǔ)Activity,每次打開一個(gè)新activity或者退出當(dāng)前activity時(shí),都會(huì)在一個(gè)任務(wù)棧當(dāng)中添加或刪除一個(gè)activity組件,因此一個(gè)task包含了其實(shí)是一個(gè)activity集合,android 的系統(tǒng)通過任務(wù)棧(返回棧)來有序的管理每一個(gè)Activity。在android 當(dāng)中,退出應(yīng)用程序的時(shí)候,必須要把任務(wù)當(dāng)中的所有Activity清除出棧,這時(shí)候,才能安全的,完全的退出程序。任務(wù)棧只有被銷毀了才是處于數(shù)據(jù)最安全的狀態(tài),當(dāng)然如果不去刪除它的話,一定要合理的去保存這個(gè)任務(wù)棧。這時(shí)候它這個(gè)任務(wù)棧就保留了每個(gè)activity的狀態(tài)也會(huì)保存activity的信息,但是特別要注意的是一定要安全的保存任務(wù)棧,任務(wù)棧并不是唯一的,某些情況下一個(gè)activity可以獨(dú)享一個(gè)任務(wù)棧,這就是啟動(dòng)模式當(dāng)中 的 singleInstance。如果想更詳細(xì)的了解的話,可以去看郭霖大神的Android任務(wù)和返回棧完全解析,細(xì)數(shù)那些你所不知道的細(xì)節(jié)。

圖片來源于網(wǎng)絡(luò).png

三.Activity啟動(dòng)模式

1.standard(默認(rèn)啟動(dòng)模式)
standard.png

在這種模式下,每次啟動(dòng)一個(gè)activity都會(huì)重新創(chuàng)建一個(gè)activity實(shí)例,然后將它加到任務(wù)棧當(dāng)中,就是task當(dāng)中,不會(huì)考慮這個(gè)task當(dāng)中有沒有這個(gè)實(shí)例,不會(huì)去復(fù)用這個(gè)activity,只會(huì)重新創(chuàng)建activity,在這個(gè)模式當(dāng)中,每次創(chuàng)建一個(gè)activity,都會(huì)走相應(yīng)的生命周期方法,是非常消耗資源的。

為什么android 會(huì)提供一個(gè)啟動(dòng)模式,在開發(fā)中一般都會(huì)在不同頁(yè)面間跳轉(zhuǎn),不同頁(yè)面跳轉(zhuǎn)實(shí)質(zhì)就是activity 間的跳轉(zhuǎn)。我們肯定會(huì)復(fù)用某個(gè)activity 。如果跳轉(zhuǎn)到某個(gè)原來的activity實(shí)例的時(shí)候,希望activity是復(fù)用的,而不是重新創(chuàng)建的,重新創(chuàng)建是非常消耗資源的,如果每一次創(chuàng)建一個(gè)activity都放在task當(dāng)中,就像standard模式一樣。對(duì)內(nèi)存,系統(tǒng)都是一個(gè)很大的消耗。
android 提供了第二種啟動(dòng)模式

2.singletop (棧頂復(fù)用模式)
singleTop.png

如果你創(chuàng)建的activity是在任務(wù)棧的棧頂,它就不會(huì)創(chuàng)建新的activity,而是復(fù)用棧中的activity,如果你創(chuàng)建的activity 不是在棧頂,它還是會(huì)創(chuàng)建activity的。
所以為了提高復(fù)用模式,android又提供了第三種啟動(dòng)模式

3.singletask(棧內(nèi)復(fù)用模式)
singleTask.png

它其實(shí)是一個(gè)單例模式,每一次啟動(dòng)activity時(shí),系統(tǒng)會(huì)在任務(wù)棧中檢查是否存在該活動(dòng)的實(shí)例,如果存在就直接將activity置于棧頂。注意,它把a(bǔ)ctivity置于棧頂,把這個(gè)activity以上的activity都從任務(wù)棧中移除,銷毀(在任務(wù)棧里面只允許一個(gè)實(shí)例)。

4.singleinstance(單實(shí)例模式)
singleInstance.png

這個(gè)模式比較特殊,這個(gè)activity在整個(gè)系統(tǒng)當(dāng)中有且只有一個(gè)實(shí)例,而且這個(gè)activity獨(dú)享任務(wù)棧。(例如 SecondActivity設(shè)置成singleinstance模式。讓FirstActivity跳轉(zhuǎn)到了 SecondActivity,SecondActivity跳轉(zhuǎn) ThirdActivity,然后back ,會(huì)發(fā)現(xiàn),ThirdActivity直接回到了FirstActivity再按back,才到SecondActivity,因?yàn)镕irstActivity和ThirdActivity是同一個(gè)棧的,這個(gè)棧退出空了,就會(huì)顯示另一個(gè)任務(wù)棧(返回棧)的棧頂活動(dòng))

假設(shè)我們的程序中有一個(gè)活動(dòng)是允許其他程序調(diào)用的,如果我們想實(shí)現(xiàn)其他程序和我們的程序可以共享這個(gè)活動(dòng)的實(shí)例,應(yīng)該如何實(shí)現(xiàn)呢?使用前面3種啟動(dòng)模式肯定是做不到的,因?yàn)槊總€(gè)應(yīng)用程序都會(huì)有自己的返回棧,同一個(gè)活動(dòng)在不同的返回棧中入棧時(shí)必然是創(chuàng)建了新的實(shí)例。而是用singleInstance模式就可以解決這個(gè)問題,在這種模式下會(huì)有一個(gè)單獨(dú)的返回棧來管理這個(gè)活動(dòng),不管是哪個(gè)應(yīng)用程序來訪問這個(gè)活動(dòng),都共用的同一個(gè)返回棧,也就解決了共享活動(dòng)實(shí)例的問題。 選自《第一行代碼》

四.scheme跳轉(zhuǎn)協(xié)議

android中的scheme是一種頁(yè)面內(nèi)跳轉(zhuǎn)協(xié)議,是一種非常好的實(shí)現(xiàn)機(jī)制,通過定義自己的scheme協(xié)議,可以非常方便跳轉(zhuǎn)app中的各個(gè)頁(yè)面;通過scheme協(xié)議,服務(wù)器可以定制化告訴App跳轉(zhuǎn)那個(gè)頁(yè)面,可以通過通知欄消息定制化跳轉(zhuǎn)頁(yè)面,可以通過H5頁(yè)面跳轉(zhuǎn)頁(yè)面等。

操作方法很簡(jiǎn)單,客戶端向H5頁(yè)面注冊(cè)一個(gè)URL Scheme,由Scheme協(xié)議從瀏覽器中啟動(dòng)這個(gè)Activity。Scheme應(yīng)用場(chǎng)景:
1.服務(wù)端下發(fā)一個(gè)URL的路徑然后客戶端根據(jù)服務(wù)端下發(fā)的URL跳轉(zhuǎn)到相應(yīng)的頁(yè)面。
2.從H5頁(yè)面跳轉(zhuǎn)到相應(yīng)的APP Activity
3.APP根據(jù)URL跳轉(zhuǎn)到另一個(gè)APP的指定頁(yè)面
scheme跳轉(zhuǎn)協(xié)議在開發(fā)中是極其重要的??梢钥催@篇文章詳細(xì)了解下android H5 應(yīng)用內(nèi)跳轉(zhuǎn)Scheme協(xié)議

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容