Activity A 有「傳值跳轉」與「單純跳轉」兩個按鈕。Activity B 接收時直接 getIntent().getExtras().getString(...),單純跳轉導致 getExtras() 回傳 null,拋出 NPE。
// 來源碼 (Android SDK)
public Bundle getExtras() {
return (mExtras != null) ? new Bundle(mExtras) : null; // 可能回傳 null
}
public String getStringExtra(String name) {
return mExtras == null ? null : mExtras.getString(name); // 內部已判空,不拋 NPE
}
getExtras() 會回傳 null,後續 .getString() 直接炸;但 getStringExtra() 內部已防呆,回傳 null 而非拋出例外。
// ❌ 錯誤寫法
Bundle extras = getIntent().getExtras();
String name = extras.getString("sendName"); // NPE 風險
// ✅ 正確寫法
String name = getIntent().getStringExtra("sendName"); // 無值回傳 null
int copies = getIntent().getIntExtra("sendCopies", 0); // 可指定預設值
boolean flag = getIntent().getBooleanExtra("flag", false); // 內部防呆
Intent 機制刻意不提供來源識別,以維持鬆耦合。需自行約定:
// 發送端
intent.putExtra("fromSendActivity", true);
// 接收端
if (getIntent().getBooleanExtra("fromSendActivity", false)) {
// 安全接收該 Activity 專屬資料
String name = getIntent().getStringExtra("sendName");
...
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_receive);
Intent intent = getIntent();
// 1. 識別來源 (可選)
if (!intent.getBooleanExtra("fromSendActivity", false)) return;
// 2. 安全取值 (皆有預設值)
String name = intent.getStringExtra("sendName");
String eat = intent.getStringExtra("sendEatSomething");
int copies = intent.getIntExtra("sendCopies", 1);
// 3. 非空驗證 (業務層面)
if (TextUtils.isEmpty(name)) { finish(); return; }
// 4. 更新 UI
tvName.setText(name + ": ");
tvDetail.setText("來 " + copies + " 份 " + eat);
}