首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Android 實戰:物件序列化與外部儲存權限完整實作——保存使用者偏好設定

     編輯:Java 相關知識

前言:為什麼選擇物件序列化?

Android 提供 SharedPreferences、SQLite、檔案儲存等多種持久化方案。當設定項目較多、結構複雜(如視窗大小、位置、多層巢狀偏好)時,將整個設定物件序列化為單一檔案,讀寫一次即可完成全部欄位持久化,代碼簡潔且易維護。

核心步驟

  1. 資料類別實作 Serializable 介面
  2. 使用 ObjectOutputStream / ObjectInputStream 進行檔案讀寫
  3. Android 外部儲存(SD 卡)需宣告權限並處理目錄建立
  4. UI 綁定:onCreate 讀取還原、按鈕點擊寫入

完整實作代碼

1. 資料模型 UserSetting.java


public class UserSetting implements Serializable {
    private String username;
    private int gender; // 1=男, 0=女
    private String qqNumber;
    // 建構子、getter/setter 略
}

2. 佈局 activity_main.xml(關鍵屬性)

  • EditText username / qq_number
  • RadioGroup + 兩個 RadioButton (man/female) android:onClick="choiceGender"
  • Button android:onClick="saveUserSetting"

3. 主邏輯 MainActivity.java


public class MainActivity extends Activity {
    private UserSetting mUserSetting;
    private File mAppDir, mUserSettingFile;
    private EditText mUsername, mQqNumber;
    private RadioGroup mGender;
    private int gender = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initViews();
        initStoragePaths();
        loadUserSetting(); // 讀取並回填 UI
    }

    private void initStoragePaths() {
        File sdcard = Environment.getExternalStorageDirectory(); // /storage/sdcard0
        mAppDir = new File(sdcard, "saveUserSetting");
        mUserSettingFile = new File(mAppDir, "user.setting");
        if (!mAppDir.exists()) mAppDir.mkdirs();
    }

    private void loadUserSetting() {
        if (mUserSettingFile.exists()) {
            try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(mUserSettingFile))) {
                mUserSetting = (UserSetting) ois.readObject();
                mUsername.setText(mUserSetting.getUsername());
                mQqNumber.setText(String.valueOf(mUserSetting.getQqNumber()));
                RadioButton rb = (RadioButton) mGender.getChildAt(mUserSetting.getGender() == 1 ? 0 : 1);
                rb.setChecked(true);
                gender = mUserSetting.getGender();
            } catch (Exception e) { e.printStackTrace(); }
        }
    }

    public void saveUserSetting(View v) {
        String uname = mUsername.getText().toString().trim();
        String qq = mQqNumber.getText().toString().trim();
        if (uname.isEmpty() || qq.isEmpty()) {
            Toast.makeText(this, "不能為空", Toast.LENGTH_SHORT).show();
            return;
        }
        mUserSetting = new UserSetting(uname, gender, Integer.parseInt(qq));
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(mUserSettingFile))) {
            oos.writeObject(mUserSetting);
            Toast.makeText(this, "儲存成功", Toast.LENGTH_SHORT).show();
        } catch (Exception e) { e.printStackTrace(); }
    }

    public void choiceGender(View v) {
        gender = ((RadioButton) v).getId() == R.id.man ? 1 : 0;
    }
}

AndroidManifest.xml 權限宣告(必要)




注意:Android 6.0+ (API 23) 需動態請求運行時權限,本範例為示範核心邏輯,實務上需補全 requestPermissions 流程。

關鍵目錄路徑對照表

方法回傳路徑範例說明
getDataDirectory()/data內部儲存根目錄
getExternalStorageDirectory()/storage/sdcard0外部儲存(SD 卡)根目錄
getDownloadCacheDirectory()/cache下載快取
getRootDirectory()/system系統分區

避坑指南

  1. serialVersionUID:建議顯式宣告,防止類別版本演進導致反序列化失敗。
  2. 大物件序列化會阻塞主執行緒,實務上應放入 IO 執行緒(RxJava/Coroutines/ThreadPool)。
  3. 敏感資料(Token、密碼)嚴禁明文序列化,需加密或採用 EncryptedSharedPreferences。
  4. Android 10+ (API 29) 分區儲存限制,建議改用 getExternalFilesDir() 專屬目錄,無需權限。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved