【安卓基礎3】Activity(一)

🏆作者簡介:|康有為| ,大四在讀,目前在小米安卓實習,畢業入職

🏆本文收錄于 ?安卓學習大全,歡迎關注

🏆安卓學習資料推薦:

? ? ? ? 視頻:b站搜動腦學院 視頻鏈接 (他們的視頻后面一部分沒再更新,看看前面也挺好的)

? ? ? ? 書籍:《第一行代碼》(第3版) by 郭霖 (z-lib.org)

? ? ? ? 思維導圖: https://www.processon.com/view/link/62427cb2e0b34d0730e20e00(來自動腦學院)

目錄

一、Activity入門

Activity的創建

1. 在layout目錄下創建XML文件

2. 創建與XML文件對應的Java代碼

3. 在AndroidManifest.xml中注冊頁面配置

Activity的跳轉

Activity快捷創建

二、Activity的基本用法

在Activity中使用Toast

三、Activity的啟動和結束

四、Activity的生命周期

分析Activity生命周期

將上文的細節提煉

狀態之間的切換過程

Activity A 啟動一個透明的 Activity B

異常情況下的生命周期

常見異常情況

1.資源相關的系統配置發生改變導致Activity被殺死并重新創建

2.系統內存不足導致低優先級的Activity被殺死


一、Activity入門

Activity可以理解為程序的一個界面或一個屏幕。

在Android中,Activity 是一個用于展示用戶界面和處理用戶交互的基本組件。它代表了用戶與應用程序之間的單一屏幕,用戶在應用程序中進行的每個操作通常都與一個 Activity 相關聯。在Android應用程序中,通常會包含多個活動,每個活動都代表應用程序的一個界面或一個屏幕

先用Androidstudio創建一個Empty Views Activity 的 HelloWorld程序,java語言的

Activity的創建

完整的頁面創建過程包括三個步驟,也就是創建下面的三個文件

1. layout目錄下創建XML文件

創建成功后,添加下面代碼

并在res/values/strings.xml文件 中添加文字

<resources><string name="app_name">HelloWorld-Java</string><string name="text2">文字2222222</string>
</resources>

2. 創建與XML文件對應的Java代碼

寫代碼:

1.繼承AppCompatActivity

2.重寫onCreate方法(寫onCreate會有提示,自動補全)

重寫時選擇這個protect修飾的這個onCreate方法

3.寫上:setContentView(R.layout.activity_main2);


package com.example.helloworld_java;import android.os.Bundle;import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;public class MainActivity2 extends AppCompatActivity {@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main2);}
}

3. AndroidManifest.xml中注冊頁面配置

在這里加入一行代碼,將這個activity注冊到清單文件

<activity android:name=".MainActivity2"/>

?

因為MainActivity2 不是主activity,所以不用再修改 intent-filter的代碼。

至此就創建好了 Activity2

Activity的跳轉

我們想顯示Activity2,就需要從主Activity中跳轉到2,所以寫一個按鈕,加上點擊跳轉的事件,跳轉到2。

在主Activity中加上按鈕


<Buttonandroid:id="@+id/button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="跳轉" />

?編寫跳轉事件(要寫到主Activity中的onCreate方法里面,從主Activity 跳轉到 其他Activity)


Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent();intent.setClass(MainActivity.this,MainActivity2.class);startActivity(intent);}
});

?效果

Activity快捷創建

直接在java文件包那里快捷創建

這樣layout里面也會自動幫我們創建好文件

清單文件中也會自動幫我們注冊好

快捷創建的layout中的xml文件,根是androidx.constraintlayout.widget.ConstraintLayout ,我們可以換成LinearLayout

?androidx.constraintlayout.widget.ConstraintLayoutLinearLayout 是 Android 開發中常用的兩種布局管理器,它們在布局設計和子視圖排列方面有一些不同之處。

二、Activity的基本用法

Activity中使用Toast

Toast是Android系統提供的一種非常好的提醒方式,在程序中可以使用它將一些短小的信息通 知給用戶,這些信息會在一段時間后自動消失,并且不會占用任何屏幕空間。

在Android中,Toast 是一種簡單的通知方式,可以在屏幕底部顯示一小段時間的消息。以下是在 Activity 中使用 Toast 的基本步驟:

  1. 創建 Toast 對象: 使用 Toast.makeText() 方法創建一個 Toast 對象。
  2. 設置顯示文本: 使用 setText() 方法設置要顯示的文本內容。
  3. 設置時長: 使用 setDuration() 方法設置 Toast 的顯示時長,可以選擇 Toast.LENGTH_SHORT(短時,大約2秒)或 Toast.LENGTH_LONG(長時,大約3.5秒)。
  4. 顯示 Toast: 調用 show() 方法顯示 Toast

以下是一個簡單的示例:


import android.os.Bundle;
import android.view.Gravity;
import android.widget.Toast;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 創建一個Toast對象Toast toast = Toast.makeText(this, "Hello, this is a Toast!", Toast.LENGTH_SHORT);// 設置Toast的顯示位置(可選)toast.setGravity(Gravity.CENTER, 0, 0);// 顯示Toasttoast.show();}
}

效果:

三、Activity的啟動和結束

從當前頁面跳到新頁面,跳轉代碼如下:

startActivity(new Intent(源頁面.this,目標頁面.class));

A -- B ,那么B就是啟動了

從當前頁面回到上一個頁面,相當于關閉當前頁面,返回代碼如下:

finish();//結束當前的活動頁面

B結束之后,就返回到了A

示例

從A跳到B的java代碼,xml里面寫個按鈕就行。

從B跳回A,也就是直接執行 finish 就行

四、Activity的生命周期

分析Activity生命周期

什么是 生命周期,就是從生到死的過程。

正常情況下,新建一個Activity A會順序經歷如下幾個生命周期:

  1. onCreate:A正在被創建,這個方法中,我們可以做一些Activity的初始化操作。例如布局文件的加載與事件的綁定(setContentView,findViewById,setOnClickListener等)。
  2. onStart: A 正在被啟動,A 由不可見變為可見時調用,此時 A 還無法與用戶交互。此時可以做一些數據的初始化操作(開啟線程去拉本地數據庫數據,或從后臺拉數據)。
  3. onResume: A 已經可見,并出現在前臺,該Activity位于返回棧棧頂,可以響應用戶的操作,即可以與用戶交互了。

如果此時用戶拉起另一個Activity B, Activity A會順序經歷如下幾個生命周期:

4. onPause: 表示 A 正在停止,準備從前臺返回至后臺,此時可以做一些停止動畫,數據存儲等工作。值得注意的是,在onPause生命周期進行的工作不能太耗時,不然會影響 B 的顯示。(Activity A的onPause執行完后,Activity B的onResume才會執行)。

5. onStop: 在 A 完全不可見時調用,緊隨著onPause執行,表 A 即將停止,此時 A 已經不在前臺,可以做一些稍微重量級的回收工作,但同樣不能太耗時,(如果此時新打開的Activity B是對話框式的Activity,背景存在一定區域是透明的,則Activity A的onStop不會調用)。

6. onDestroy:表示 A 即將被銷毀,在這里可以進行資源的回收、釋放工作。一般是經過用戶按下back鍵或者系統資源緊張時,將Activity A釋放掉以獲得更多的內存時調用。

Activity B經歷了onResume生命周期后已經顯示在前臺,如果此時按下back返回鍵,從 B 頁面返回,而 A 還停留在onStop,沒有經過onDestroy生命周期的話,A 會經歷如下幾個生命周期后重新顯示:

7. onRestart: A 由onStop停止狀態,轉為運行狀態時調用,表 A 正在被重新啟動。

8. onStart

9. onResume

可以看到,排除Activity退到后臺的情況,Activity從創建到銷毀,總共會經過6個生命周期,分別是onCreate,onStart,onResume,onPause,onStop,onDestroy。

通過上面的文字描述,看這個圖應該已經很清楚了,不過,未提到的是,上圖中onPause()還有個箭頭指向了onResume(),這是一種極端情況。即考慮當Activity A 跳轉到Activity B 的情況,此時 A 還在執行onPause() , B 還未顯示出來。快速地從B回到A,此時會直接執行 A 的onResume()而不會走onRestart()。不過一般很難復現這種操作,大家留個心眼就行。

將上文的細節提煉

  • onStart、onResume、onPause、onStop看起來回調調用的時機差不多,它們倆區別在哪呢?

onStart和onStop是從Activity是否可見的角度來回調的,而onResume和onPause則是從Activity是否位于前臺、是否可以與用戶交互的角度來回調的,除了這方面的差別,在時機使用過程中,它們沒有其他明顯區別。

  • 從Activity A 跳轉到Activity B,是先執行 A 的onPause(),還是先執行 B 的onResume()呢?

這部分設計Activity跳轉的源碼,源碼邏輯太深、太復雜就不先在基礎篇討論了,大家目前 先記住結論就好:A onPause()會先執行,然后才執行 B onResume(),這個細節也是面試中可能會問到的點。

  • 在onPause中不能進行耗時的操作,否則會影響新Activity的顯示,稍微重一點的操作可以放在onStop中,但依然不能太耗時。

狀態之間的切換過程

打開新頁面的方法調用順序為:

onCreate→onStart→onResume

關閉舊頁面的方法調用順序為:

onPause→onStop→onDestroy

Activity A 啟動一個透明的 Activity B

  • 如果 Activity A 啟動一個透明的 Activity B,會經歷哪些生命周期呢?

這是面試容易遇到的一個問題,因為 B 頁面透明, 所以跳轉到 B 頁面后,A 頁面依然可見,因此就不會調用 Activity A onStop 方法。

一般情況,A/B 均不是透明頁面:

A 跳轉 B 頁面會經歷的生命周期:A.onPause() -> B.onCreate() -> B.onStart() -> B.onResume() -> A.onStop。

從 B 頁面返回 A 頁面經歷的生命周期:B.onPause() -> A.onRestart() -> A.onStart() -> A.onResume() -> B.onStop()。

B是透明頁面的情況:

如果 B 是透明的,A 跳轉到 B:A.onPause() -> B.onCreate() -> B.onStart() -> B.onResume()。

從 B 返回 A:B.onPause() -> A.onResume() -> B.onStop()

異常情況下的生命周期

考慮一種異常情況,Activity C 打開了Actvity D后,C進入了停止狀態(調用了onStop()),此時系統內存不足,需要回收 C(調用C的onDestroy()) ,當用戶從 D 返回到 C,C 會被重新創建(調用onCreate())。如果原來 C 里邊有臨時狀態存儲著,比如TextView中的文字。那么從 D 返回 C 時,C因為重新創建,如果TextView未指定ID,那它原來的文字就會消失,這一定程度影響了用戶的體驗。

因此為了優化用戶體驗,Activity提供了一個onSaveInstanceState()回調方法,這個方法可以保證異常情況下,在Activity被回收之前一定會被調用。

onSaveInstanceState()方法會攜帶一個bundle參數,我們可以通過bundle對象,存儲一些簡單的狀態信息。

Activity重新創建后,系統會調用onRestoreInstanceState(),并把Activity銷毀時onSaveInstanceState()方法所保存的Bundle對象作為參數同時傳遞給onRestoreInstanceState()onCreate()

你可以選擇這兩個方法中任意一個來恢復數據,二者的區別是:onRestoreInstanceState一旦被調用,其bundle對象一定是有值的,而onCreate在正常啟動Activity的情況下bundle對象是無值的。

調用時機

onSaveInstanceState()onStop()之前調用,onRestoreInstanceState()會在onStart()之后調用。

異常情況下,Activity數據的存儲和恢復的生命過程都是一樣的。

常見異常情況

常見的異常情況主要有以下兩種:

1.資源相關的系統配置發生改變導致Activity被殺死并重新創建

首先說說什么是系統配置信息。

不同手機設備的分辨率不同,要將圖片適配不同大小的手機屏幕,我們通常會在drawable-xhdpi,drawable-xxhdpi,drawable-xxxhdpi等目錄中存放對應大小的圖片Resource文件。

當App啟動時,系統就會根據當前設備的屏幕情況去加載合適的Resource資源。同一臺設備的橫屏和豎屏時的屏幕大小也是不一樣的,如果當前Activity處于豎屏狀態,突然旋轉至橫屏,那么此時系統的屏幕配置發生了改變。

默認情況下,Activity會被銷毀并重建。因為這種銷毀是一種非用戶主導的、異常的情況,Activity會調用onSaveInstanceState()方法后銷毀,重建時會再調用onRestoreInstanceState()方法,即走一遍異常情況的生命周期。

如何避免這種因為系統配置更改而導致Activity重建的異常情況?

如果app在應用配置變更期間無需更新資源,我們可以在AndroidManifest.xml文件中相應的Activity聲明,自行處理相關配置的變更,從而阻止系統重建Activity。

只需指定相關的configChanges屬性。比如下面的例子,就阻止了當屏幕發生旋轉時Activity的系統自動重建。


<activity android:name=".MainActivity"android:configChanges="orientation|screenSize" />

當configChanges中指定的配置發生變化時,系統會調用Activity的onConfigurationChanged()方法,如果有需要處理配置變更的話,可以在這個方法手動處理。一般我們在屏幕旋轉時,希望Activity能保持原樣,不重建就好了,所以空實現該方法即可。

當然,需要自行處理時,比如檢查當前設備的方向,你可以這么寫:


override fun onConfigurationChanged(newConfig: Configuration) {super.onConfigurationChanged(newConfig)// Checks the orientation of the screenif (newConfig.orientation === Configuration.ORIENTATION_LANDSCAPE) {Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show()} else if (newConfig.orientation === Configuration.ORIENTATION_PORTRAIT) {Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show()}
}

configChanges屬性可以指定很多屬性,如果你還想指定更多配置,不同配置間用"|"分隔,比如上面那樣。

部分常用的configChanges配置項目如下:

2.系統內存不足導致低優先級的Activity被殺死

這種情況就是我們分析異常情況下的生命周期時舉的例子。Activity C 跳轉至Activity D,C 處于后臺,當系統內存資源不足時,C的優先級較低,會被系統銷毀以獲得更多的內存,然后再從 D 回到 C ,C 會被重建,走一遍異常時的數據存儲和恢復的生命過程。

Activity按照優先級從高到低,可以分為如下三中情況:

  • 前臺Activity,正在與用戶交互的Activity,其優先級最高。
  • 可見但非前臺Activity,比如Activity中彈出了一個對話框,導致Activity可見但出于后臺,無法與用戶直接交互。
  • 后臺Activity,已經被暫停的Activity,比如執行了onStop,用戶看不見,優先級最低。

當系統內存不足時,系統會按照上述優先級的順序去殺死Activity所在的進程。并在后續通過onSaveInstanceState()和onRestoreInstanceState()去存儲和恢復數據。

如果一個進程中沒有四大組件在執行,那么這個進程將會很快被系統殺死,因此一些后臺工作不適合脫離四大組件而單獨運行在后臺中。比較好的方法是將后臺的工作放到Service服務中,從而保證進程有一定的優先級,就不會容易被系統殺死了。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/696367.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/696367.shtml
英文地址,請注明出處:http://en.pswp.cn/news/696367.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

微信小程序開發教程:

準備工作 下載并安裝微信開發者工具注冊微信公眾平臺賬號并創建小程序項目 項目結構 app.js&#xff1a;小程序的入口文件&#xff0c;用于定義全局變量和函數app.json&#xff1a;小程序的全局配置文件&#xff0c;用于配置小程序的頁面、窗口樣式、網絡超時時間等app.wxss&am…

反光衣實時識別檢測系統-反光衣穿戴識別系統-智慧工地系統安全帽佩戴---豌豆云

反光衣實時識別檢測系統是根據視頻流的自動化圖像識別檢測&#xff0c;運用前沿的深度神經網絡與云計算技術&#xff0c;替代工作人員的眼睛。 在工地、化工廠、煤礦石化等生產安全地區部署反光衣實時識別檢測系統&#xff0c;運用現場已有的視頻監控可以無死角全自動檢測生產…

Sora橫空出世!AI將如何撬動未來?

近日&#xff0c;OpenAI 發布首個視頻生成“Sora”模型&#xff0c;該模型通過接收文字指令&#xff0c;即可生成60秒的短視頻。 而在2022年末&#xff0c;同樣是OpenAI發布的AI語言模型ChatGPT&#xff0c;簡化了文本撰寫、創意構思以及代碼校驗等任務。用戶僅需輸入一個指令&…

【IC設計】Chisel API之Arbiter和RRArbiter的使用

文章目錄 介紹Chisel的Valid和Ready流控build.sbtRRArbiter代碼示例 介紹 仲裁器在NoC路由器中是重要的組成部分&#xff0c;虛通道仲裁和交叉開關仲裁都需要使用仲裁器。 Chisel提供了Arbiter和RRArbiter仲裁器 Arbiter是基礎的低位優先仲裁器&#xff0c; RRArbiter初始情況…

前端構建效率優化之路

項目背景 我們的系統&#xff08;一個 ToB 的 Web 單頁應用&#xff09;前端單頁應用經過多年的迭代&#xff0c;目前已經累積有大幾十萬行的業務代碼&#xff0c;30 路由模塊&#xff0c;整體的代碼量和復雜度還是比較高的。 項目整體是基于 Vue TypeScirpt&#xff0c;而構…

ProtoBuf認識與Windows下的安裝

protobuf簡介 Protobuf 是 Protocol Buffers 的簡稱&#xff0c;它是 Google 公司開發的一種數據描述語言&#xff0c;是一種輕便高效的結 構化數據存儲格式&#xff0c;可以用于結構化數據&#xff0c;或者說序列化。它很適合做數據存儲 或 RPC 數據交換格 式 。可用于通訊…

WebServer -- 定時器處理非活動連接(上)

目錄 &#x1f34d;函數指針 &#x1f33c;基礎知識 &#x1f419;整體概述 &#x1f382;基礎API sigaction 結構體 sigaction() sigfillset() SIGALRM, SIGTERM 信號 alarm() socketpair() send() &#x1f4d5;信號通知流程 統一事件源 信號處理機制 &#x…

2024全球網絡安全展望|構建協同生態,護航數字經濟

2024年1月&#xff0c;世界經濟論壇發布《2024全球網絡安全展望》報告&#xff0c;指出在科技快速發展的背景下&#xff0c;網絡安全不均衡問題加劇&#xff0c;需加強公共部門、企業組織和個人的合作。 報告強調&#xff0c;面對地緣政治動蕩、技術不確定性和全球經濟波動&am…

基于springboot+vue的美發門店管理系統(前后端分離)

博主主頁&#xff1a;貓頭鷹源碼 博主簡介&#xff1a;Java領域優質創作者、CSDN博客專家、阿里云專家博主、公司架構師、全網粉絲5萬、專注Java技術領域和畢業設計項目實戰&#xff0c;歡迎高校老師\講師\同行交流合作 ?主要內容&#xff1a;畢業設計(Javaweb項目|小程序|Pyt…

Python 高級語法:一切皆對象

1 “一切皆對象”是一種核心設計哲學 在編程領域&#xff0c;特別是面向對象編程&#xff08;OOP&#xff09;中&#xff0c;“一切皆對象”是一種核心設計哲學。這種哲學主張&#xff0c;無論是數據、函數、還是更復雜的結構&#xff0c;都可以被視為對象&#xff0c;并賦予…

信息安全基本概念匯總

目錄 一、安全加密算法相關 二、信息安全需求規范相關 三、安全啟動 四、安全更新 五、安全通信SecOC 六、HSM安全固件整體架構 一、安全加密算法相關 基于Autosar的網絡安全理解_搜狐汽車_搜狐網 基于AES的CMAC算法、MAC、Hash、數字簽名之間的關系_aes cmac-CSDN博客…

Cartographer框架簡述

catographer框架分為前端和后端 前端包括雷達數據處理&#xff1b;位姿預測&#xff1b;掃描匹配和柵格地圖更新。 后端包括后端&#xff1a;線程池任務與調度&#xff1b;向位姿圖添加節點&#xff0c;計算節點的子圖內約束和子圖間約束&#xff08;回環檢測&#xff09;&…

C++之Easyx——圖形庫的基本功能(1):界面操作

最近&#xff0c;我覺得使用控制臺編寫游戲太沒意思了&#xff01;&#xff01; 所以我開始研究圖形庫了~ 一、setinitmode 函數定義 void EGEAPI setinitmode(int mode, int x CW_USEDEFAULT, int y CW_USEDEFAULT); //設置初始化模式&#xff0c;mode0為普通&#xff0c…

Spark中寫parquet文件是怎么實現的

背景 本文基于 Spark 3.5.0 寫本篇文章的目的是在于能夠配合spark.sql.maxConcurrentOutputFileWriters參數來加速寫parquet文件的速度&#xff0c;為此研究一下Spark寫parquet的時候會占用內存的大小&#xff0c;便于配置spark.sql.maxConcurrentOutputFileWriters的值&#…

Javascript怎么輸出內容?兩種常見方式以及控制臺介紹

javascript是一種非常重要的編程語言&#xff0c;在許多網頁中它被廣泛使用&#xff0c;可以實現許多交互效果和動態效果。輸出是javascript中最基本的操作之一&#xff0c;下面將介紹兩種常見的輸出方式。 一、使用console.log()函數輸出 console.log()函數是常用的輸出函數…

Jmeter實現階梯式線程增加的壓測

安裝相應jmeter 插件 1&#xff1a;安裝jmeter 管理插件&#xff1a; 下載地址&#xff1a;https://jmeter-plugins.org/install/Install/&#xff0c;將下載下來的jar包放到jmeter文件夾下的lib/ext路徑下&#xff0c;然后重啟jmeter。 2&#xff1a;接著打開 選項-Plugins Ma…

在Linux上安裝Docker: 一站式指南

Docker 是一款強大的容器化平臺&#xff0c;為開發者提供了一種輕松打包、發布和運行應用的方式。在本文中&#xff0c;我們將探討如何在Linux操作系統上安裝Docker&#xff0c;為你提供一站式指南。 步驟1: 卸載舊版本 在安裝新版Docker之前&#xff0c;建議先卸載舊版本&am…

三十年一個大輪回!日股突破“泡沫時期”歷史高點

2月22日周四&#xff0c;英偉達四季報業績超預期&#xff0c;而且本季度業績指引非常樂觀&#xff0c;提振美股股指期貨并成為芯片股和AI概念股情緒的重要催化劑。今日亞洲芯片股和AI股起飛&#xff0c;日本在芯片股的帶動下突破1989年泡沫時期以來的歷史最高收盤價。 美股方面…

我之前炒股虧麻了,找百融云AI Agent談了談心

春節之前&#xff0c;A股和H股都跌麻了&#xff0c;但是機構的路演和調研反而多了。因為&#xff1a;寫不完的安撫、說不完的陪伴、聽不完的客戶指責、以及撿不完的AH股便宜貨。 有一位血液里流淌著美式咖啡的職場白領&#xff0c;雖然這些年在股市過得很不如意&#xff0c;但…

C語言---鏈表

一.定義 鏈表是由一系列節點組成&#xff0c;每個結點包含兩個域&#xff0c;一個是數據域&#xff0c;數據域用來保存用戶數據&#xff0c;另一個是指針域&#xff0c;保存下一個節點的地址。鏈表在內存中是非連續的。 二.分類 靜態鏈表 動態鏈表 單向鏈表 雙向鏈表 循環鏈…