Activity onCreate() 中初始化大量 View、綁定監聽器、載入資料導致啟動卡頓、ANR 風險。本文提供分級優化策略:生命週期調整、異步載入、ViewBinding、依賴注入架構。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
super.onResume(); // ❌ 錯誤:onCreate 中調用 onResume,破壞生命週期
// 大量 findViewById、setOnClickListener、資料載入...
et = findViewById(R.id.et);
// ... 20+ 個 View 初始化
et.addTextChangedListener(textWatcher); // textWatcher 未定義
}
| 問題 | 影響 | 修正 |
|---|---|---|
super.onResume() 在 onCreate 中 | 生命週期亂序、狀態不一致 | 刪除,生命週期由系統自動調用 |
大量 findViewById 同步執行 | 主執行緒阻塞、啟動慢 | ViewBinding / DataBinding 編譯期生成 |
| 監聽器/適配器/資料庫/網路在 onCreate | ANR、UI 凍結 | 移至 onStart/onResume、ViewModel、Coroutine/Flow |
未定義變數 textWatcher | 編譯錯誤 | 補全定義或移除 |
// build.gradle (app)
android {
buildFeatures {
viewBinding true
}
}
// Activity
private ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
// 直接使用 binding.et, binding.btnSin... 無需 findViewById
binding.et.addTextChangedListener(textWatcher);
}
優點:型別安全、Null 安全、效能最快、程式碼簡潔。
| 生命週期 | 職責 | 範例 |
|---|---|---|
onCreate | 佈局膨脹、ViewBinding、關鍵狀態恢復、ViewModel 獲取 | binding = ...; viewModel = new ViewModelProvider(this).get(MyVM.class); |
onStart | 註冊廣播、傳感器、開始動畫、啟動前台服務 | registerReceiver(...); sensorManager.registerListener(...); |
onResume | 恢復獨佔資源 (相機、麥克風)、恢復音樂播放、埋點頁面曝光 | cameraProvider.bindToLifecycle(...); resumeAnalytics(); |
onPause | 釋放獨佔資源、暫停動畫、隱藏敏感資訊 | cameraProvider.unbindAll(); pauseAnalytics(); |
onStop | 註銷廣播、停止傳感器、保存草稿 | unregisterReceiver(...); saveDraft(); |
onDestroy | 清理 ViewBinding、取消協程、關閉資料庫連線 | binding = null; coroutineScope.cancel(); db.close(); |
// ViewModel
class CalculatorViewModel : ViewModel() {
private val _display = MutableStateFlow("0")
val display: StateFlow = _display
fun onDigit(digit: String) { /* 純邏輯,無 Android 依賴 */ }
fun onOperator(op: String) { /* ... */ }
fun onEqual() { /* ... */ }
}
// Activity
private val viewModel: CalculatorViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
// UI 狀態收集 (生命週期感知)
lifecycleScope.launch {
viewModel.display.collect { binding.et.setText(it) }
}
binding.btnSin.setOnClickListener { viewModel.onOperator("sin") }
// ...
}
優點:Activity 變薄、邏輯可測試、配置變更 (旋轉) 自動保留狀態、協程結構化併發。
// 大型資料載入、資料庫遷移、第三方 SDK 初始化
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// UI 先顯示骨架屏/進度條
binding = ...
setContentView(binding.root)
// IO 密集型任務放入 IO 調度器
lifecycleScope.launch(Dispatchers.IO) {
val data = repository.loadInitialData()
withContext(Dispatchers.Main) {
adapter.submitList(data)
binding.progressBar.visibility = View.GONE
}
}
}
adb shell am start -S -W com.pkg/.MainActivity 獲取啟動耗時。遵循「ViewBinding 消除樣板碼、生命週期分工、ViewModel 下沉邏輯、協程異步初始化」四步走,徹底解決 onCreate 臃腫導致的啟動卡頓與 ANR 風險。