三三要成為安卓糕手
一:Activity之間的數據傳輸
問題:不同的Activity之間怎么進行數據傳輸呢?
比如第一個頁面中有一些字符串數據之類的要通過數據傳輸,傳遞給第二個頁面進行顯示的
1:MainActivity做處理
在定義一個按鈕,和一個文本輸入框
<Buttonandroid:id="@+id/btn_second3"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="攜帶數據,跳轉到Second頁面"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@id/btn_second2"/><EditTextandroid:id="@+id/et_data"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="請輸入一些數據"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@id/btn_second3"/>
findViewById(R.id.btn_second3).setOnClickListener(this);etData = findViewById(R.id.et_data);
繼續在onClick方法中寫一個else if()
else if (id == R.id.btn_second3) {Intent intent = new Intent(this, SecondActivity.class);String string = etData.getText().toString();if(string != null && string.length() > 0){intent.putExtra("key_data",string); }startActivity(intent);}
(1)putExtra
Extra
翻譯為額外;它的作用是在通過 Intent 啟動另一個組件(如 Activity)時,攜帶一些額外的數據
有點Cookie和Session會話的味道了,記住這里的key值一定要匹配
(2)邏輯梳理
從輸入框中獲取string字符串
2:SecondActivity做處理
xml布局自己定義一個TextView,此處略
Intent intent = getIntent();String keyData = intent.getStringExtra("key_data");TextView textView = findViewById(R.id.text_view);if(keyData != null && keyData.length() > 0){textView.setText(keyData);}
這邊呢接收數據,并讓string顯示在頁面上
看一下兩者聯系
3:效果
效果就這樣,第二個頁面(右圖)接受到了,就顯示出來
二:Activity之間的數據回傳
問題:MainActivity怎么接收SecondActivity回傳的數據
1:MainActivity做處理
(1)startActivityForResult
<Buttonandroid:id="@+id/btn_second4"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="跳轉到Second頁面,等待Second返回數據"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@id/et_data"/>
findViewById(R.id.btn_second4).setOnClickListener(this);
else if (id == R.id.btn_second4) {//老方式startActivityForResult(new Intent(this, SecondActivity.class),9);}
-
startActivityForResult方法在安卓API30以后已經過時了,但是很多商業中也會用到這個玩意,也得學bro
- 參數一:Intent 對象,“要啟動哪個頁面”,也可以在
Intent
里用putExtra
攜帶數據傳給目標頁面。 - 參數二:requestCode(請求碼),給這次跳轉打個 “標記 9”,等目標頁面返回數據時,能通過這個標記識別 “這是 btn_start_second4 按鈕跳轉的返回”。
- 參數一:Intent 對象,“要啟動哪個頁面”,也可以在
(2)onActivityResult
@Overrideprotected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {super.onActivityResult(requestCode, resultCode, data);if (requestCode == 9 && resultCode == 8){int keyComeBackNum = data.getIntExtra("key_comeBackNum", 0);String keyComeBackString = data.getStringExtra("key_comeBackString");Log.i(TAG, "onActivityResult: num = " + keyComeBackNum);Log.i(TAG, "onActivityResult: string = " + keyComeBackString);etData.setText(keyComeBackNum + keyComeBackString);}}
-
requestCode
:“請求碼”,自己定義的一個整數標記,這里是9; 區分 “是哪一次啟動 Activity 的請求”- 比如:一個頁面有多個按鈕,都用
startActivityForResult
跳轉到不同頁面,靠requestCode
就知道 “這次返回的數據,對應之前哪個按鈕的跳轉” 。
- 比如:一個頁面有多個按鈕,都用
-
resultCode
:“結果碼”,是目標 Activity 返回的狀態標記 -
data
:一個Intent
對象,是目標 Activity 返回的 “數據載體”; 記得判空- getInExtra取到的值如果為空,默認為0
2:SecondActivity做處理
在SecondActivity的xml中在定義一個Button控件
<Buttonandroid:id="@+id/btn_back"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="往MainActivity回傳數據"app:layout_constraintTop_toTopOf="parent"app:layout_constraintStart_toStartOf="parent"/>
(1)setResult
findViewById(R.id.btn_back).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {int comeBack = 798;String string = "surprise ma da faker";Intent backIntent = new Intent();backIntent.putExtra("key_comeBackNum",comeBack);backIntent.putExtra("key_comeBackString",string);setResult(8,backIntent);finish();}});
- setResult(8,backIntent),這里我們的結果碼就是8
3:邏輯梳理
-
啟動時:
- 通過
startActivityForResult(intent, 9)
啟動SecondActivity
,這里的9
就是requestCode
(請求碼)。
- 通過
-
目標頁面返回時:
在SecondActivity
中,需要通過setResult(8, data)
來設置返回結果:- 第一個參數
8
就是resultCode
(結果碼,自定義的標記) - 第二個參數
data
是Intent
對象,通過putExtra
存入數據(key_comeBackNum
和key_comeBackString
)
- 第一個參數
-
接收返回時:回到當前頁面的
onActivityResult
方法:- 通過
requestCode == 9
判斷:“這是之前用請求碼 9 啟動的頁面返回的結果” - 通過
resultCode == 8
判斷:“目標頁面返回了結果碼 8 的狀態” - 從
data
中取出攜帶的key_comeBackNum
和key_comeBackString
,并更新到etData
輸入框中
- 通過
4:finish問題延伸
提問:在第二個頁面做了一些數據后,不馬上finish,而是手動關閉,這個時候回傳的數據還能收到嗎
最后一句代碼finish刪掉;finish的作用就是,點擊btn_bakc2這個按鈕后activity_second
這個頁面就退出了
這里我們點擊返回按鈕,同樣MainActivity能接收到傳回來的數據,并不受影響
三:Activity數據回傳的新方式
1:.launch
用于啟動目標 Activity 并等待其返回結果的核心方法。它的作用類似于傳統的 startActivityForResult()
創建點擊事情的準備工作
//跳轉到第二個頁面,等待回傳數據else if (id == R.id.btn_second5) {activityResultLancher.launch(new Intent(this, SecondActivity.class));}
2:registerForActivityResult
可以理解一個接收Activity結果的注冊器,負責 “結果回調”,能在當前 Activity中優雅接收、處理返回的數據。
是傳統的startActivityForResult
+ onActivityResult
機制的平替
private ActivityResultLauncher<Intent> activityResultLancher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {@Overridepublic void onActivityResult(ActivityResult o) {int resultCode = o.getResultCode();//返回的結果碼Intent data = o.getData();//返回的數據if (resultCode == 8) {int keyComeBackNum = data.getIntExtra("key_comeBackNum", 0);String keyComeBackString = data.getStringExtra("key_comeBackString");Log.i(TAG, "onActivityResult: key_comeBackNum = " + keyComeBackNum);Log.i(TAG, "onActivityResult: key_comeBackString" + keyComeBackString);etData.setText("接受到的數據是" + keyComeBackString + keyComeBackNum);}}});
(1)new ActivityResultContracts.StartActivityForResult()
作用:啟動一個 Activity 并獲取其返回結果
ActivityResultContracts
是一個包含多種預定義合約(Contract)的工具類,StartActivityForResult
是其中一個靜態內部類
(2)new ActivityResultCallback()
作用:回調接口,當被啟動的 Activity 關閉并返回結果時觸發
重寫onActivityResult方法,((20250808114147-zw40xjr “前面我們已經使用過這個方法,但是兩者形參不同,”))ActivityResult
中包括結果碼(resultCode) 和 返回的數據(data)