Android四大組件之Activity

来源:https://www.cnblogs.com/xmkh/archive/2019/08/28/11423183.html
-Advertisement-
Play Games

前言 Hi,大家好,又見面啦,上一期我們講瞭如何安裝AS,是不是已經有小伙伴迫不及待的創建了自己的項目並開始嘗試了呢?那麼這一期我們主要為大家介紹Activity。作為Android的四大組件之一,Activity占據著非常重要的作用。本文將圍繞Android的生命周期、啟動模式、基本配置等方面進行 ...


前言

Hi,大家好,又見面啦,上一期我們講瞭如何安裝AS,是不是已經有小伙伴迫不及待的創建了自己的項目並開始嘗試了呢?那麼這一期我們主要為大家介紹Activity。作為Android的四大組件之一,Activity占據著非常重要的作用。本文將圍繞Android的生命周期、啟動模式、基本配置等方面進行介紹。

簡介

應用程式的每一個界面都是一個Activity,所以也有人稱其為視圖界面。從字面的意思去理解,Activity具有活動的意思,我們在應用中進行的操作都是集中在Activity上面完成,例如撥號、拍照、發送email、看地圖。每一個activity被給設置到一個視窗,在上面可以繪製交互界面。 一個應用程式通常由多個activities組成,他們通常是松耦合關係,通常一個應用程式包含有一個主Activity,即點擊桌面圖標的時候首先進入的Activity。

Android創建與啟動

以一個簡單的Activity的創建與使用示說明:

創建

在Androd Studio 新建項目完成後,會自動創建一個 Java 文件,這個文件就是 Activity,因為它繼承系統 framework 層提供的 Activity,這裡 AppCompatActivity 是 Activity 的子類,我們的 MainActivity 間接繼承 Activity。

並且你會看到 MainActivity 強制重寫了 onCreate 方法,在 onCreate 中,通過 setContentView 為 Activity 設置我們自定義的頁面佈局文件。

註冊Activity

在 manifest 中註冊Activity

    
<activity
            android:name=".MainActivity"
            android:configChanges="orientation|screenSize"
            android:label="@string/app_name"
            android:launchMode="standard">
            <intent-filter>
                <action android:name="myactoin2" />
                
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
      </activity>

 

Activity 必須在 AndroidManifest.xml 註冊,如果沒有註冊這 Activity 就不能正常運行,其實在正常情況下在使用Android 中的四大組件(Activity,Service,BrocastReceiver,ContentProvider)時都需要再 AndroidManifest.xml 中註冊。在上面的 xml 註冊信息中,其中 <inten-filter>中指定

<action android:name="android.intent.action.MAIN" />   
<category android:name="android.intent.category.LAUNCHER" />

 

表明這個Activity是主Activity,在Android系統點擊應用圖標首先進入主Activity。

啟動

Activity是通過Intent用來在應用程式的Activity間啟動、停止和傳輸。

啟動Activity的三種方法:

1、顯示啟動

在這裡註冊了第二個Activity ---- SecondActivity ,並且牢記前面的註冊操作,我們把 SecondActivity 註冊到 Manifest 文件中。現在就可以在 MainActivity 中啟動 SecondActivity。

Intent intent = new Intent(this, SecondActivity.class);
//通過上下文Context和SecondActivity.java類的Class對象,創建 Intent 對象 
startActivity(intent);//調用系統Framework 層提供的方法,啟動 SecondActivity。

 

2、隱式啟動

若 SecondActivity 在AndroidManifest.xml文件中配置 intent-filter 的 action 和 category、data,如下:

<intent-filter>    
   <action android:name="myaction2"/>    
   <category android:name="android.intent.category.DEFAULT"/>    
   <category android:name="mycategory" />
</intent-filter>

 

那麼可以通過如下方式啟動 SecondActivity :

Intent intent = new Intent("myaction2");
startActivity(intent);

 

3、預設啟動

通過桌面圖標點擊應用圖標進入程式的第一個Activity,因其啟動方式有別上述兩個方式,將其劃分為第三類的啟動方式。 若Activity在AndroidManifest.xml文件的intent-filter的action和category,如下:

<intent-filter>    
   <action android:name="android.intent.action.MAIN" />    
   <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

 

那麼,點擊桌面的應用圖標即可啟動Activity。

註:如果在N個Activity中都配置上述的action和category,那麼桌面會有N個應用的圖標,點擊不同的圖標會進入對應的Activity。

Activity的生命周期

Activity 的生命周期如下圖:

(1) onCreate

表示Activity正在被創建,這是第一個執行的方法,在Activity的生命周期中只執行一次。在這個方法中做一些初始化工作,比如調用setContentView去載入界面佈局,初始化Activity所需要的數據等。後續調用onStart()。

(2) onRestart

表示Activity正在重新啟動,一般情況下,當前的Activity從不可見的狀態變為可見狀態時,onRestart就會被調用。這種情形一般是用戶操作出現所致,比如用戶按Home鍵回到桌面或者用戶打開了一個新的Activity,這時候Activity就會暫停,接著用戶又回到該Activity。後續調用onStart()。

(3) onStart

表示Activity正在被啟動,即將開始。這個時候Activity是可見的,但是還沒有出現在前臺,不能和用戶進行交互。這個時候可以理解為Activity已經顯示出來,但是我們還看不到。後續的方法是onResume()。

(4) onResume

表示Activity可見,並且已經出現在前臺並開始活動,能和用戶正常進行交互。需要註意的是onStart和onResume的區別,二者都是Activity可見,但是onStart時Activity還在後臺,而onResume時Activity到了前臺了,這時候可以開啟動畫或者獲取獨占性設備的操作如打開相機、獲取麥克風等。

(5) onPause

表示Activity由前臺轉到後臺,正常情況下,緊接著onStop就會被調用。這時仍然可見。如果這時候快速地回到當前Activity,那麼onResume會被調用,這類情況屬於極端情況,用戶操作很難重現這一場景。此時可以做一些存儲數據,停止動畫等操作,但是註意不能太耗時,如果太耗時會影響到新的Activity的顯示。onPause是先執行完,新的Activity的onCreate才會執行。onResume和onPause相對應。

(6) onStop

表示Activity即將停止,當前的Activity對用戶不在可見。可稍微做些重量級的回收操作。後續的操作可能是onRestart或者onDestroy或者一直保持這個狀態。

(7) onDestory

表示Activity正在被銷毀,是生命周期的最後一個回調,也是只調用一次。發生的條件是Activity本身已經執行完畢,或者系統資源不足需要回收資源將Activity銷毀。

我們考慮如下幾類情況: 1、當一個Toast彈出的時候,會發生回調麽? No 2、當一個AlertDialog彈出的時候,會發生回調麽? No, 如果AlertDialog獲取焦點,Activity會觸發onWindowFocusChanged回調 3、當一個PopWindow彈出的時候,會發生回調麽? No, 如果PopWindow獲取焦點,如mPopupWindow.setFocusable(true),Activity會觸發onWindowFocusChanged回調。 4.橫豎屏切換時,會造成Activity被銷毀然後重新創建。若在Activity配置android:configChanges="orientation",橫豎屏切換時,只觸發onConfigurationChanged( )回調,Activity不會被重新創建。

啟動模式

Activity 有四種啟動模式,不同的模式,對應這 Activity 對象的創建於復用策略,可以在 Manifest 和 代碼中指定 Activity 的啟動模式。

在探究什麼是啟動模式之前要弄請幾個問題:

  1. 啟動模式原理(什麼是任務棧)?

  2. 為什麼會需要啟動模式?

  3. 四種任務棧的特點?

  4. 使用方式

  5. 應用場景

什麼是任務棧

Android 任務棧又稱為 Task,它是一個棧類型的數據結構:先進先出。它用於存儲我們的 Activity 組件。

每次打開一個新的 Activity 或 退出一個 Activity 都會在任務棧的結構中添加或減少一個 Activity,一個任務棧包含了一個 Activity 集合。Android 系統可以通過 Task 有序的管理每個 Activity ,並決定那個 Activity 與用戶進行交互:只用在棧頂的 Activity 才可以跟用戶進行交互。

在應用程式退出時,必須把所有任務棧中的 Activity 清除棧時,任務棧才會被銷毀。當然任務棧可以移動到後臺,並且保存每個 Activity 的狀態。可以有序的給用戶列出Activity的任務,同時也不會丟失 Activity 的信息。

應用程式中可能不止一個任務棧,某系情況情況下,單獨的一個 Activity 可以獨享一個任務棧,也會存在一個任務棧的 Activity 可以來自不同的 App,同一個 App 中的 Activity 可能在不同的任務棧當中。

為什麼會需要啟動模式

在應用程式開發過程中,一般都需要在多個 Activity 組件之間跳轉,也可能需要在本應用中打開其他應用的可復用的 Activity。在開發過程中需要跳轉到原來已經開啟的 Activity 實例,此時我們希望這個 Activity 可以被重用而不是再重新創建一個新的 Activity 實例,但根據 Android 系統的預設行為,每次都會為我們創建一個新的 Activity 實例對象並添加到任務棧中,而且 Activity 的數據和信息狀態都將會被保留

我們可以在 MainActivity 中添加一個按鈕,點擊按鈕跳轉到 SecondActivity,然後在 SecondActivity 中添加兩個按鈕,點擊一個按鈕跳轉到 MainActvity,在另一個按鈕的點擊事件中添加如下代碼:

//獲取ActivityMananger
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
//獲取任務棧 可能是多個
List<ActivityManager.RunningTaskInfo> runningTasks = am.getRunningTasks(5);
//獲取當前的任務棧
ActivityManager.RunningTaskInfo runningTaskInfo = runningTasks.get(0);
//獲取當前任務棧中 Activity 個數,即當前沒有換存活的 Activity 實例個數。
int numRunning = runningTaskInfo.numRunning;
//Log 列印信息
Log.e("SecondActivity", "numRunning" + numRunning);

 

上面代碼不用深究,主要目的是想說明系統預設情況下,當前任務棧中存活的 Activity 實例個數。當我們在 MainActvity 中點擊按鈕跳轉到 SecondActivity ,當跳轉到 SecondActivity 在點擊第一個按鈕跳轉到 MainActivity ,不斷重覆這個操作。最後當跳轉的 SecondActivity 點擊第一個按鈕獲取當前任務棧中的 Activity 個數。下麵是方法和其對應運行時對應結果。

這樣造成數據沉餘,重覆數據太多,最終可能還會導致記憶體溢出(OOM)。為解決這些問題,Android 系統提供了一套 Activity的啟動模式來修改預設的 Activity 啟動模式。

四種任務棧的特點
  • Standard 模式(一般模式)

系統預設模式,每次啟動一個Activity都會重新創建一個新的實例,而不管Activity是否已經創建了一個實例。

  • SingTop (棧頂復用模式)

棧頂復用模式,系統啟動時,系統會啟動當前棧頂Activity是不是要啟動的Activity,如果是則不需要創建新的Activity而直接引用這個Activity,如果不是那麼創建新的Activity。系統會回調Activity的onNewIntent()的方法。

  • SingTask(棧內復用模式)

棧內復用模式,如果棧內已經存在了一個Activity的實例,那麼Activity不會被重新創建,同時這個Activity的onNewIntent()方法會被回調,並將該Activity實例置於棧頂,原先處於該實例頂部的Activity實例會被出棧銷毀。如果是其他程式啟動Activity,那麼它會重新創建一個任務棧。

  • SingleInstance(單一實例模式)

單實例模式,是singleTask的加強版,具有singleTask所有特點,並且此種模式下Activity只有一個實例,並且只能單獨的存在一個任務棧中。

使用方式

啟動模式一般分為兩種:

  1. 在 AndroidManifes.xml 中 ,找到聲明 Activity 的位置,在 Actvity XML 屬性 android:launchMode="standard",其他模式(singleTop,singleTask,singleInstance) 聲明。

  2. 在代碼中跳轉 Activity 時,利用 Intent 指定 Flag 標誌位來使用啟動模式。示例代碼如下:

Intent intent = new Intent(this, SecondActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//Flag
startActivity(intent);

 

setFlags方法說明

//使用一個新的Task來啟動Activity,但每個Activity都將在一個新的Task中。
Intent.FLAG_ACTIVITY_NEW_TASK   
//使用singleTop模式來啟動一個Activity。  
Intent.FLAG_ACTIVITY_SINGLE_TOP  
//使用singleTask模式來啟動一個Activity。
Intent.FLAG_ACTIVITY_CLEAR_TOP
//使用singleTask模式來啟動一個Activity,使用這種方式啟動Activity,當Activity啟動其他Activity的時候,該Activity會被銷毀,不入棧。  
Intent.FLAG_ACTIVITY_NO_HISTORY
//方式無法指定 SingleInstance 模式,SingleInstances 只能在 AndroidManifest.xml 中聲明。
Intent.setFlags

 

常見使用場景

這裡是一些在開發中常見的業務場景頁面使用的頁面啟動模式:

結語

作為Android的四大組件之一,並且也是項目開發過程中最常用到的,小伙伴們要深刻理解,並把它靈活的運用到項目中,當然這些也是面試中會問到的最基礎問題。

PS:如果還有未看懂的小伙伴,歡迎關註我們WXGZH:下碼看花,裡面有各種大神回答小伙伴們遇到的問題哦~

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 設置主機名 [root@localhost ~]# cat /etc/hosts127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4::1 localhost localhost.localdomai... ...
  • 前言 最近在處理一個歷史遺留項目的時候飽受其害,主要表現為偶發性的 SharedPreferences 配置文件數據錯亂,甚至丟失。經過排查發現是多進程的問題。項目中有兩個不同進程,且會頻繁的讀寫 SharedPreferences 文件,所以導致了數據錯亂和丟失。趁此機會,精讀了一遍 Shared ...
  • 本篇概要 小程式開發前的準備 小程式視圖與渲染 小程式事件 註:總的來說,微信小程式的開發代碼寫法,和 HTML、CSS、JavaScript類似很像.jpg 一,微信小程式開發前的準備 於微信小程式官網進行註冊 ==> https://mp.weixin.qq.com/cgi-bin/wx 註冊完 ...
  • void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);然後在創建上下文以pxdata 所指向的記憶體作為上下文數據存貯的容器, 最後 渲染 上下文[self.webView.layer renderInContext:context];這樣就將 we ...
  • 使用SharedPreferences(保存用戶偏好參數)保存數據, 當我們的應用想要保存用戶的一些偏好參數,比如是否自動登陸,是否記住賬號密碼,是否在Wifi下才能 聯網等相關信息,如果使用資料庫的話,顯得有點大材小用了!我們把上面這些配置信息稱為用戶的偏好 設置,就是用戶偏好的設置,而這些配置信 ...
  • 問題 問題 ld: library not found for -lstdc++.6.0.9 clang: error: linker command failed with exit code 1 (use -v to see invocation) 官方解釋 官方解釋 Xcode更新後沒有這個庫 ...
  • 前言 Hi,大家好,上一期我們講瞭如何使用BroadcastReceiver,這一期我們講解Android四大組件之Service相關知識。每天一篇技術乾貨,每天我們一起進步。 耐心專註不僅僅是美德,更是一筆財富。 1.簡介與定義 Service是一個可以在後臺執行長時間運行操作而不提供用戶界面的應 ...
  • 前言 Hi,大家好,又雙見面啦,上一期我們講瞭如何使用Activity,肯定有不少小伙伴已經創建了屬於自己的FirstActivity,那麼這一期我們主要為大家介紹第二個重要組件BroadcastReceiver(廣播接收器)。作為Android的四大組件之二,其應用場景非常多。下麵,就詳細介紹下 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...