原問題嘗試在 Activity A 中通過 findViewById 直接操作 Activity C 的 TextView,這違反 Android 組件生命週期:非當前顯示的 Activity 其視圖層級可能未創建、已銷毀、或根本不存在。正確做法是傳遞數據而非控件引用。
// ❌ 錯誤:嘗試在 Activity A 直接訪問 Activity C 的 View
TextView tv = (TextView) findViewById(R.id.showmsg); // 這裡的 R.id 屬於當前 Activity 佈局
tv.setText("data"); // 即使不崩潰,也操作的是 Activity A 自己的 View
// Activity A (發送方)
Intent intent = new Intent(this, ActivityC.class);
intent.putExtra("USER_NAME", "張三");
intent.putExtra("USER_ID", 1001);
startActivity(intent);
// Activity C (接收方) - onCreate 中
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_c); // 先 setContentView
TextView tv = findViewById(R.id.showmsg); // 再 findViewById
String name = getIntent().getStringExtra("USER_NAME");
int id = getIntent().getIntExtra("USER_ID", -1);
tv.setText("歡迎 " + name + " (ID: " + id + ")");
}
// 寫入 (任意位置,如登錄成功後)
Context context = getApplicationContext();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
prefs.edit().putString("USER_NAME", "張三").apply();
// 讀取 (Activity C onCreate)
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
String name = prefs.getString("USER_NAME", "訪客");
findViewById(R.id.showmsg).setText(name);
// SharedViewModel (Application 或 Activity 作用域)
class UserViewModel : ViewModel() {
val userName = MutableLiveData()
fun updateName(name: String) {
userName.value = name
}
}
// Activity A (更新數據)
val viewModel: UserViewModel by viewModels() // 或 activityViewModels()
viewModel.updateName("張三")
startActivity(Intent(this, ActivityC::class.java))
// Activity C (觀察數據)
val viewModel: UserViewModel by activityViewModels() // 共享同一實例
viewModel.userName.observe(this, { name ->
findViewById(R.id.showmsg).text = name ?: "訪客"
})
class MyApp : Application() {
var currentUser: User? = null
}
// 任意處存取
(MyApp)getApplication().currentUser = user
val name = ((MyApp)getApplication()).currentUser?.name
| 原則 | 錯誤做法 | 正確做法 |
|---|---|---|
| 數據與視圖分離 | 跨 Activity 直接操作 View | 傳遞數據模型,各 Activity 綁定自己的 View |
| 生命週期安全 | 持有其他 Activity/View 引用 | 用 Intent/ViewModel/存儲傳遞不可變數據 |
| 單一職責 | Activity 既負責導航又負責數據存儲 | ViewModel 處理數據,Activity 僅負責 UI 渲染 |
android:text="TEST" 驗證 View 可見性。Log.d(TAG, "Extra: " + getIntent().getStringExtra("KEY")) 確認數據到達。findViewById 是否返回 null(通常是 setContentView 前調用、或 ID 錯誤)。記住:Activity 之間傳遞的是「數據」,不是「控件」。這是 Android 組件化設計的基石。