在 onCreate() 中執行某段初始化邏輯(如引導頁、數據遷移、權限申請、配置初始化),要求應用生命週期內僅執行一次,後續啟動自動跳過。
public class MainActivity extends AppCompatActivity {
private static final String PREFS_NAME = "AppInitPrefs";
private static final String KEY_FIRST_RUN = "isFirstRun";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 檢查是否首次運行
if (isFirstRun()) {
// 執行一次性初始化邏輯
performFirstRunInitialization();
// 標記為已初始化
markFirstRunComplete();
}
// 正常業務邏輯...
}
private boolean isFirstRun() {
SharedPreferences prefs = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
return prefs.getBoolean(KEY_FIRST_RUN, true); // 默認 true(首次)
}
private void markFirstRunComplete() {
SharedPreferences prefs = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
prefs.edit().putBoolean(KEY_FIRST_RUN, false).apply(); // 異步寫入
}
private void performFirstRunInitialization() {
// 具體業務:顯示引導頁、預載數據、申請權限、創建默認配置等
showGuidePages();
initDefaultSettings();
preloadCriticalData();
}
}
應用升級後需重新執行某些遷移邏輯:
private static final String KEY_LAST_VERSION_CODE = "lastVersionCode";
private boolean shouldRunForCurrentVersion() {
SharedPreferences prefs = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
int lastVersionCode = prefs.getInt(KEY_LAST_VERSION_CODE, -1);
int currentVersionCode = BuildConfig.VERSION_CODE;
if (lastVersionCode < currentVersionCode) {
// 版本升級或首次安裝
prefs.edit()
.putInt(KEY_LAST_VERSION_CODE, currentVersionCode)
.putBoolean(KEY_FIRST_RUN, false)
.apply();
return true;
}
return false;
}
| 方案 | 適用場景 | 優點 | 缺點 |
|---|---|---|---|
| SharedPreferences | 輕量級標識、配置存儲 | API 簡單、進程安全、跨進程可用 | 不適合大數據、頻繁讀寫 |
文件標識(.nomedia等) | 極簡場景、無需結構化數據 | 零依賴、可見性強 | 無結構、易誤刪、并發風險 |
| DataStore (Jetpack) | 現代應用、協程支持、類型安全 | 異步一致性、Flow API、遷移友好 | 需添加依賴、學習曲線 |
| 數據庫標記 | 已有數據庫、複雜狀態機 | 事務支持、查詢靈活 | 過重、啟動延遲 |
apply() 而非 commit() 異步寫入,不阻塞主線程isFirstRun()、markComplete()、performInit() 單一職責MODE_MULTI_PROCESS 或遷移至 DataStoreApplication.onCreate() 中判斷:可能因多進程、組件啟動順序導致重複執行savedInstanceState:僅用於配置變更重建,不適用於冷啟動