淺談一下Android的Activity
前言 :
Android 系統(tǒng)的四大組件分別是
1 活動(dòng) (Activity)
2 服務(wù)(Service)
3 廣播接收器(Broadcast Receiver)
4 內(nèi)容提供器 (Content Provider)
其中活動(dòng)是所有安卓應(yīng)用程序的門(mén)面,凡事你在應(yīng)用中看到的東西,都是放到活動(dòng)中的。
一 Activity 啟動(dòng)和結(jié)束
1 從當(dāng)前頁(yè)面跳轉(zhuǎn)到下個(gè)頁(yè)面, startActivity(原頁(yè)面.this,目標(biāo)頁(yè)面.class)
// 跳轉(zhuǎn)到下一個(gè)頁(yè)面 startActivity(new Intent(MainActivity.this, ActFinishActivity.class));
2 結(jié)束返回
finish 結(jié)束當(dāng)前頁(yè)面進(jìn)行返回
@Override public void onClick(View view) { if (view.getId() == R.id.goBack){ finish(); } }
二 Activity 生命周期
1 Activity 的四種狀態(tài)
1> 運(yùn)行中(Running/Active),這是Activity 位于棧頂庫(kù),是可見(jiàn)的,可以與用戶(hù)交互。
2> 暫停(Paused),當(dāng)Activity 失去焦點(diǎn),不能跟用戶(hù)交互了,但依然可見(jiàn),就會(huì)處于暫停狀態(tài)。
當(dāng)一個(gè)新的非全屏的Activity或者一個(gè)透明的Activity 放置在棧頂,Activity 就處于暫停狀態(tài)。
3> 停止 (Stoped),當(dāng)一個(gè)Activity 被另外一個(gè)Activity完全覆蓋,或者點(diǎn)擊Home鍵進(jìn)入了后臺(tái),這時(shí)候就處于停止?fàn)顟B(tài)。這個(gè)時(shí)候數(shù)據(jù)還保存著。
4> 銷(xiāo)毀(Destroyed) ,點(diǎn)擊返回鍵或者系統(tǒng)在內(nèi)存不夠用的情況下就會(huì)把Activity 從棧里移除銷(xiāo)毀。
2 流程解讀
1> 在Activity 運(yùn)行之前,會(huì)調(diào)用onCreate,onStart,onResume 這三個(gè)方法,之后Activity 就處于Running 狀態(tài)了
2> 當(dāng)Activity 暫停時(shí)候,會(huì)調(diào)用onPause, Activity 重新恢復(fù)到運(yùn)行狀態(tài)的時(shí)候,會(huì)運(yùn)行onResume
3> Activity 處理停止?fàn)顟B(tài)時(shí),會(huì)調(diào)用onStop。這個(gè)時(shí)候如果要恢復(fù)運(yùn)行狀態(tài)就會(huì)調(diào)用一個(gè)新的方法onRestart,然后再去調(diào)用onStart,onResume
4>當(dāng)Activity被銷(xiāo)毀的時(shí)候,會(huì)調(diào)用onDestroy方法
3 具體功能
1 onCreate: 當(dāng)Activity第一次被創(chuàng)建時(shí)調(diào)用。是生命周期開(kāi)始的第一個(gè)方法。在這里我們可以做一些初始化的操作,比如:調(diào)用setContentView()方法去加載界面,綁定布局里的一些控件,初始化一些Activity需要用到的數(shù)據(jù)。之后會(huì)調(diào)用onStart方法.
2 onStart:當(dāng)Activity正在變?yōu)榭梢?jiàn)時(shí)調(diào)用。這個(gè)時(shí)候Activity已經(jīng)可見(jiàn)了,但是還沒(méi)有出現(xiàn)在前臺(tái)還不能跟用戶(hù)交互??梢院?jiǎn)單理解為Actvity已經(jīng)可見(jiàn)但是還沒(méi)有出現(xiàn)在前臺(tái)。之后會(huì)調(diào)用onResume.
3 onResume:當(dāng)Activity可以跟用戶(hù)交互時(shí)調(diào)用,這個(gè)時(shí)候,這個(gè)Activity位于棧的頂部。跟onStart相比,它們都是表示Activity已經(jīng)可見(jiàn),但是onStart調(diào)用時(shí)Activity還在后臺(tái),而調(diào)用onResume時(shí),Activity已經(jīng)進(jìn)入了前臺(tái),可以跟用戶(hù)交互了。之后會(huì)調(diào)用 onPause.
4 onPause:當(dāng)Activity暫停時(shí)調(diào)用這個(gè)方法;在這里我們可以用來(lái)保存數(shù)據(jù),關(guān)閉動(dòng)畫(huà)和其它比較耗費(fèi)CPU的操作;但是在這里做的操作絕對(duì)不能耗時(shí),因?yàn)槿绻?dāng)前Activity要啟動(dòng)一個(gè)新的Activity,這個(gè)新的Activity會(huì)在當(dāng)前Activity執(zhí)行完畢onPause之后才能進(jìn)入可見(jiàn)狀態(tài)。這個(gè)方法之后一般會(huì)調(diào)用的方法有onStop或者onResume. ==在Android3.0之前,調(diào)用這個(gè)方法之后,Activity可能會(huì)在系統(tǒng)內(nèi)存緊張時(shí)被系統(tǒng)回收==
5 onStop:當(dāng)Activity進(jìn)入后臺(tái),并且不會(huì)被用戶(hù)看到時(shí)調(diào)用。當(dāng)別的Activity出現(xiàn)在前臺(tái)時(shí),或者Activity會(huì)被銷(xiāo)毀時(shí),調(diào)用此方法;在這個(gè)方法調(diào)用之后,系統(tǒng)可能會(huì)在內(nèi)存不夠的情況下回收Activity;在這個(gè)方法之后一般會(huì)調(diào)用onRestart或者onDestroy.
6 onDestroy:這個(gè)方法是Activity生命周期中調(diào)用的最后一個(gè)方法。它會(huì)在Activity被銷(xiāo)毀之前調(diào)用;Activity銷(xiāo)毀原因一般是我們調(diào)用Activity的finish方法手動(dòng)銷(xiāo)毀,另一個(gè)就是系統(tǒng)在內(nèi)存緊張的情況下去銷(xiāo)毀Activity,以用來(lái)節(jié)省空間。我們可以通過(guò)方法 isFinishing 來(lái)判斷Activity是否正在被銷(xiāo)毀。
7 onRestart:這個(gè)方法是在Activity處于停止?fàn)顟B(tài)后,又回到可視狀態(tài)時(shí)調(diào)用。之后會(huì)調(diào)用onResume
4 總結(jié)
1 打開(kāi)新頁(yè)面
onCreate --> onStart --> onRume
2 關(guān)閉舊頁(yè)面
onPause --> onStop --> onDestroy
三 Activity 啟動(dòng)模式分類(lèi)
這個(gè)模式可以在Mainifest.xml 文件中設(shè)定,如果不設(shè)定,默認(rèn)就是standard
1 Standard 標(biāo)準(zhǔn)模式
這個(gè)模式啟動(dòng)的Activity 會(huì)按照啟動(dòng)順序依次壓入到Task 棧中
2 SingleTop 棧頂復(fù)用模式
如果棧頂Activity 為我們 要新創(chuàng)建的Activity,那么久不回重復(fù)創(chuàng)建新的Activity
3 SingleTask 棧內(nèi)復(fù)用模式
若 需要?jiǎng)?chuàng)建的Activity 已經(jīng)處于棧中時(shí),此時(shí)不會(huì)創(chuàng)建新的Activity ,而是將其上面的其他Activity 全部銷(xiāo)毀,使其成為棧頂,
4 SingleInstance 單實(shí)例模式
具有此模式的Activity 僅僅單獨(dú)處于一個(gè)任務(wù)棧中
四 啟動(dòng)模式的設(shè)置
1 在Manifest.xml 中指定Activity 啟動(dòng)模式
<activity android:name=".MainActivity" android:exported="true" android:launchMode="singleTask" >
2 在啟動(dòng)Activity 時(shí),在Intent 中指定啟動(dòng)模式去創(chuàng)建Activity
Intent intent = new Intent(MainActivity.this, ActFinishActivity.class); // 棧中存在待跳轉(zhuǎn)的實(shí)例時(shí),重新創(chuàng)建該活動(dòng)的實(shí)例,并且清除原來(lái)實(shí)例上方所有的實(shí)例 intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); // 跳轉(zhuǎn)到下一個(gè)頁(yè)面 startActivity(intent);
以上兩種方式都能為Activity 設(shè)置啟動(dòng)模式,可是二者還是有差別的。
優(yōu)先級(jí) :動(dòng)態(tài)指定的優(yōu)先級(jí)較高
限定范圍:靜態(tài)指定方式無(wú)法為Activity 直接指定 FLAG_ACTIVITY_CLEAR_TOP 標(biāo)識(shí),
動(dòng)態(tài)指定無(wú)法為Activity 指定singleInstance 模式
五 Activity Flags
1 FLAG_ACTIVITY_NEW_TASK
開(kāi)辟一個(gè)新的任務(wù)棧
2 FLAG_ACTIVITY_SINGLE_TOP
當(dāng)棧頂為待跳轉(zhuǎn)的活動(dòng)實(shí)例之時(shí),則重用棧頂?shù)膶?shí)例
3 FLAG_ACTIVITY_CLEAR_TASK
跳轉(zhuǎn)到新頁(yè)面的時(shí)候,棧中原油的實(shí)例都被清空
4 FLAG_ACTIVITY_CLEAR_TOP
棧中存在待跳轉(zhuǎn)的實(shí)例時(shí),重新創(chuàng)建該活動(dòng)的實(shí)例,并且清除原來(lái)實(shí)例上方所有的實(shí)例
六 Intent
各個(gè)組件之間信息溝通的橋梁?jiǎn)幔糜贏ndroid各個(gè)組件之間的通信。
* 1 標(biāo)明本次通信從哪里來(lái)嗎,到哪里去,要怎么走
* 2 發(fā)起方攜帶本次通信需要的數(shù)據(jù)內(nèi)容,接收方從收到的意圖中解析出數(shù)據(jù)
* 3 發(fā)起方若想判斷接收方的處理結(jié)果,意圖就要負(fù)責(zé)讓接收方傳回應(yīng)答的數(shù)據(jù)內(nèi)容。
1 顯式Intent
明確指定要跳轉(zhuǎn)的Activity
創(chuàng)建方式1 直接初始化
Intent intent = new Intent(MainActivity.this, ActFinishActivity.class);
創(chuàng)建方式2 setClass
Intent intent2 = new Intent(); intent2.setClass(MainActivity.this,ActFinishActivity.class);
創(chuàng)建方式3 setComponent
Intent intent3 = new Intent(); ComponentName component = new ComponentName(MainActivity.this,ActFinishActivity.class); intent3.setComponent(component);
2 隱式Intent
沒(méi)有明確要跳轉(zhuǎn)的目標(biāo)Activity,只給出一個(gè)動(dòng)作字符串讓系統(tǒng)自動(dòng)匹配,屬于模糊匹配。
比如說(shuō)
打電話 ACTION_DIAL
發(fā)短信 ACTION_SENDTO
當(dāng)然了 還可以跳轉(zhuǎn)自己定義的頁(yè)面,不過(guò)自己定義的需要設(shè)置一下 Manifest.xml
exported = true
IntentFilter在xml中的三個(gè)主要的參數(shù):action,categary,data。
<activity android:name=".ActFinishActivity" android:exported="true" > <intent-filter> <action android:name="android.intent.action.myselfActivity"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </activity>
switch (view.getId()){ case R.id.jump_to_tel: { Intent intent = new Intent(); intent.setAction(Intent.ACTION_DIAL); Uri uri = Uri.parse("tel:123456789"); intent.setData(uri); startActivity(intent); } break; case R.id.jump_to_sms: Intent intent2 = new Intent(); intent2.setAction(Intent.ACTION_SENDTO); // 123456789 為發(fā)送目標(biāo) Uri uri2 = Uri.parse("sms:123456789"); intent2.setData(uri2); startActivity(intent2); break; // 跳轉(zhuǎn)我自己的頁(yè)面 case R.id.jump_to_my_self: Intent intent3 = new Intent(); intent3.setAction("android.intent.action.myselfActivity"); intent3.addCategory(Intent.CATEGORY_DEFAULT); startActivity(intent3); break; default: throw new IllegalStateException("Unexpected value: " + view.getId()); }
七 傳遞數(shù)據(jù)
1 向目標(biāo)Activity 傳遞數(shù)據(jù)
傳遞數(shù)據(jù)是使用Bundle 來(lái)實(shí)現(xiàn)的。其內(nèi)部就是一個(gè)Map,用起來(lái)也和map 相差無(wú)幾
原界面?zhèn)鬟f數(shù)據(jù)
Intent intent = new Intent(MainActivity.this,ActFinishActivity.class); // 傳遞信息到下個(gè)界面 通過(guò)bundle 包裝數(shù)據(jù) Bundle bundle = new Bundle(); bundle.putString("params","go on my lady"); intent.putExtras(bundle); startActivity(intent);
目標(biāo)界面接收數(shù)據(jù)
// 獲取數(shù)據(jù) Bundle bundle = getIntent().getExtras(); String value = bundle.getString("params"); tv.setText(value); Log.e("Fibonacci", "onCreate: "+value);
2 回傳信息
這個(gè)時(shí)候要使用 ActivityResultLauncher 這個(gè)東西 了。其目的用于簡(jiǎn)化頁(yè)面中跳轉(zhuǎn)獲取返回值以及請(qǐng)求權(quán)限。
ActivityResultLauncher必須在onCreate或者onAttach方法下初始化。
在原頁(yè)面中代碼
跳轉(zhuǎn)頁(yè)面的時(shí)候 是 register.launch(intent);
package com.example.leonardoday1; import android.app.Activity; import android.content.ComponentName; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.TextView; import androidx.activity.result.ActivityResult; import androidx.activity.result.ActivityResultCallback; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import androidx.appcompat.app.AppCompatActivity; import java.net.URI; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private static final String TAG = "Fibonacci"; private ActivityResultLauncher<Intent> register; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.send_next_msg).setOnClickListener(this); TextView tv = findViewById(R.id.main_tv); register = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() { @Override public void onActivityResult(ActivityResult result) { if (result != null){ Intent intent = result.getData(); if (intent != null && result.getResultCode() == Activity.RESULT_OK){ // 獲取返回的數(shù)據(jù) Bundle bundle = intent.getExtras(); String string = bundle.getString("params"); tv.setText(string); Log.e(TAG, "onActivityResult: " + string); } } } }); } @Override public void onClick(View view) { switch (view.getId()){ case R.id.send_next_msg: { Intent intent = new Intent(MainActivity.this,ActFinishActivity.class); // 傳遞信息到下個(gè)界面 通過(guò)bundle 包裝數(shù)據(jù) Bundle bundle = new Bundle(); bundle.putString("params","go on my lady"); intent.putExtras(bundle); register.launch(intent); } break; default: throw new IllegalStateException("Unexpected value: " + view.getId()); } } }
在目標(biāo)頁(yè)面的代碼
// 反回信息給上個(gè)界面 Intent intent = getIntent(); Bundle bundle = new Bundle(); bundle.putString("params","i have receive your message"); intent.putExtras(bundle); setResult(Activity.RESULT_OK,intent); // 返回上個(gè)界面 finish();
到此這篇關(guān)于淺談一下Android的Activity的文章就介紹到這了,更多相關(guān)Android的Activity內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android調(diào)用OpenCV2.4.10實(shí)現(xiàn)二維碼區(qū)域定位
這篇文章主要為大家詳細(xì)介紹了Android調(diào)用OpenCV 2.4.10實(shí)現(xiàn)二維碼區(qū)域定位,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-03-03Android 使用volley過(guò)程中遇到的問(wèn)題解決辦法
這篇文章主要介紹了Android 使用volley過(guò)程中遇到的問(wèn)題解決辦法的相關(guān)資料,需要的朋友可以參考下2017-06-06Android側(cè)邊欄滑動(dòng)切換的view效果
這篇文章主要介紹了Android側(cè)邊欄滑動(dòng)切換的view效果,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-03-03Android中庫(kù)項(xiàng)目的使用方法圖文介紹
類(lèi)似開(kāi)發(fā)其他Java應(yīng)用一樣,我們可以將可復(fù)用的代碼,打成一個(gè)jar包,供所有需要的項(xiàng)目使用。這樣,可以解決很大一部分代碼復(fù)用的問(wèn)題,本文將詳細(xì)介紹,需要了解的朋友可以參考下2012-12-12關(guān)于Gradle下載失敗問(wèn)題的快速解決方法
這篇文章主要給大家分享了關(guān)于Gradle下載失敗問(wèn)題的快速解決方法,文中介紹了兩種解決方法,分別是使用已存在的gradle版本和手動(dòng)下載gradle,文中介紹的非常詳細(xì),需要的朋友們下面來(lái)一起看看吧。2017-05-05Android事件分發(fā)之View事件處理關(guān)鍵及示例分析
這篇文章主要為大家介紹了Android事件分發(fā)之View事件處理關(guān)鍵及示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02Android自定義控件實(shí)現(xiàn)支付寶記賬餅圖
這篇文章主要為大家詳細(xì)介紹了Android自定義控件實(shí)現(xiàn)支付寶記賬餅圖,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04