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

Android 應用啟動時僅執行一次邏輯:SharedPreferences 實現首次運行標識

     編輯:程式設計疑難解答

核心需求

在 onCreate() 中執行某段初始化邏輯(如引導頁、數據遷移、權限申請、配置初始化),要求應用生命週期內僅執行一次,後續啟動自動跳過。

標準解決方案:SharedPreferences 持久化標識

實現代碼

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、遷移友好需添加依賴、學習曲線
數據庫標記已有數據庫、複雜狀態機事務支持、查詢靈活過重、啟動延遲

最佳實踐清單

  1. ✅ 使用 apply() 而非 commit() 異步寫入,不阻塞主線程
  2. ✅ 定義常量鍵名,避免拼寫錯誤
  3. ✅ 邏輯與標識分離:isFirstRun()、markComplete()、performInit() 單一職責
  4. ✅ 考慮「清除數據」場景:用戶在設置中清除應用數據後,標識重置,邏輯重新執行(符合預期)
  5. ✅ 多進程應用:使用 MODE_MULTI_PROCESS 或遷移至 DataStore
  6. ✅ 測試驗證:首次安裝 → 運行 → 關閉 → 重啟 → 驗證邏輯未執行

常見誤區

  • ❌ 在 Application.onCreate() 中判斷:可能因多進程、組件啟動順序導致重複執行
  • ❌ 使用靜態變量標識:進程重啟後失效,無法持久化
  • ❌ 依賴 savedInstanceState:僅用於配置變更重建,不適用於冷啟動
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved