首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android setResult 數據傳遞機制詳解:為什麼 startActivity 無法接收返回值?

     編輯:程式設計綜合問答

Android 開發中,setResult() 配合 startActivityForResult() 是 Activity 間雙向通訊的標準方式。但許多開發者困惑:為什麼用 startActivity() 啟動的 Activity 無法透過 onActivityResult() 接收返回值?

核心結論先行

只有使用 startActivityForResult() 啟動的 Activity,目標 Activity 調用 setResult() 後,呼叫者的 onActivityResult() 才會被觸發並接收數據。
startActivity() 啟動的 Activity 即使調用 setResult(),系統也不會回傳結果給啟動者。

機制原理深度解析

1. startActivityForResult() 流程

// Activity A (呼叫者)
Intent intent = new Intent(this, ActivityB.class);
startActivityForResult(intent, REQUEST_CODE); // 帶請求碼啟動

// Activity B (被呼叫者)
Intent resultIntent = new Intent();
resultIntent.putExtra("key", "返回的數據");
setResult(RESULT_OK, resultIntent); // 設定結果
finish(); // 必須 finish 才會觸發回傳

// Activity A 接收
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
        String value = data.getStringExtra("key");
    }
}

2. 為什麼 startActivity() 不行?

Android 系統內部維護一個 ActivityResultRegistry,只有透過 startActivityForResult() 才會註冊回調記錄。startActivity() 只是單向啟動,不建立結果回傳管道。目標 Activity 的 setResult() 數據會隨著 finish() 丟棄,系統不會嘗試傳遞給不存在的接收者。

3. 現代替代方案:Activity Result API (AndroidX)

自 AndroidX Activity 1.2.0 起,推薦使用註冊回調方式,避免請求碼衝突:

// 在 Activity A 中註冊
private ActivityResultLauncher mStartForResult = registerForActivityResult(
    new ActivityResultContracts.StartActivityForResult(),
    result -> {
        if (result.getResultCode() == Activity.RESULT_OK) {
            Intent data = result.getData();
            // 處理返回數據
        }
    });

// 啟動
Intent intent = new Intent(this, ActivityB.class);
mStartForResult.launch(intent);

常見誤區與最佳實踐

  • 誤區:以為 setResult() 後不需 finish() 也能回傳 → 必須 finish() 才會觸發回傳
  • 誤區:在 onActivityResult() 中直接使用 data.getExtras() 不判空 → 必須判斷 data != null
  • 最佳實踐:使用 Intent.FLAG_ACTIVITY_FORWARD_RESULT 實現鏈式轉發結果
  • 最佳實踐:請求碼使用 enum 或常數管理,避免硬編碼衝突

總結:startActivity() 是「發後不理」,startActivityForResult() 才是「有來有往」。理解這一機制差異,避免在單向導航場景誤用結果回傳 API,才能寫出穩健的 Android 應用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved