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

Android 開發:Activity 間數據傳遞與持久化保存——使用 SharedPreferences 實現跨啟動訪問

     編輯:程式設計綜合問答

業務場景

列表頁點擊項目跳轉詳情頁,詳情頁接收 Intent 數據(如 selected ID)。用戶返回列表頁後再次點擊其他項目跳轉同一詳情頁實例(singleTask 模式),需在詳情頁對比「上次 selected ID」與「本次 selected ID」決定是否刷新數據。

問題分析

Activity 被系統銷毀後(內存不足、用戶滑動關閉),成員變量數據丟失。需將「上次 selected ID」持久化保存,下次啟動時讀取對比。

解決方案:SharedPreferences 持久化存儲

詳情頁接收並保存數據


public class AppDescriptionActivity extends AppCompatActivity {
    private static final String PREFS_NAME = "app_detail_prefs";
    private static final String KEY_LAST_SELECTED_ID = "last_selected_id";
    
    private String mLastSelectedId = "";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_app_description);
        
        // 1. 讀取上次保存的 selected ID
        loadLastSelectedId();
        
        // 2. 獲取本次 Intent 傳遞的數據
        Intent intent = getIntent();
        if (intent != null) {
            String currentSelectedId = intent.getStringExtra("SELECTEDID");
            String name = intent.getStringExtra("NAME");
            String amount = intent.getStringExtra("AMT");
            String count = intent.getStringExtra("COUNT");
            
            // 3. 對比判斷是否需刷新
            if (!TextUtils.equals(mLastSelectedId, currentSelectedId)) {
                // ID 變化:刷新 UI、請求新數據
                refreshUI(name, amount, count, currentSelectedId);
                // 4. 保存本次 ID 供下次對比
                saveLastSelectedId(currentSelectedId);
            } else {
                // ID 相同:可選擇不刷新或部分更新
            }
        }
    }
    
    private void loadLastSelectedId() {
        SharedPreferences sp = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
        mLastSelectedId = sp.getString(KEY_LAST_SELECTED_ID, "");
    }
    
    private void saveLastSelectedId(String selectedId) {
        SharedPreferences sp = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
        sp.edit().putString(KEY_LAST_SELECTED_ID, selectedId).apply();
        mLastSelectedId = selectedId; // 更新內存緩存
    }
    
    private void refreshUI(String name, String amount, String count, String selectedId) {
        // 更新 TextView、ImageView、發起網絡請求等
    }
}

關鍵點說明

方案適用場景優點缺點
SharedPreferences少量鍵值對、跨進程/啟動持久化簡單、系統管理、支持多進程不適合大數據、複雜結構
成員變量Activity 存活期間臨時數據極快、無 I/O銷毀即丟失
ViewModel配置變更/導航保持數據生命週期感知、自動保存恢復進程死亡仍丟失
文件/數據庫大量結構化數據功能強大複雜度高

現代替代:ViewModel + SavedStateHandle


public class AppDetailViewModel extends ViewModel {
    private final SavedStateHandle handle;
    private String lastSelectedId = "";
    
    public AppDetailViewModel(SavedStateHandle handle) {
        this.handle = handle;
        lastSelectedId = handle.get("last_selected_id", "");
    }
    
    public void updateSelectedId(String newId) {
        if (!TextUtils.equals(lastSelectedId, newId)) {
            lastSelectedId = newId;
            handle.set("last_selected_id", newId); // 自動持久化
            // 觸發 UI 刷新
        }
    }
}

優勢:自動處理配置變更、進程恢復、跨 Fragment 共享,無需手動 SharedPreferences 代碼。

最佳實踐建議

  • ✅ 使用 getSharedPreferences(name, MODE_PRIVATE) 而非 PreferenceManager.getDefaultSharedPreferences,隔離業務數據。
  • ✅ Key 定義為 static final String 常量,避免拼寫錯誤。
  • ✅ 寫入用 apply() 異步提交,讀取用 getString(key, "") 提供默認值。
  • ✅ 內存緩存 mLastSelectedId 避免頻繁磁盤讀取。
  • ✅ 新項目優先考慮 ViewModel + SavedStateHandle 替代手動 SP。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved