Android 提供 SharedPreferences、SQLite、檔案儲存等多種持久化方案。當設定項目較多、結構複雜(如視窗大小、位置、多層巢狀偏好)時,將整個設定物件序列化為單一檔案,讀寫一次即可完成全部欄位持久化,代碼簡潔且易維護。
Serializable 介面ObjectOutputStream / ObjectInputStream 進行檔案讀寫onCreate 讀取還原、按鈕點擊寫入
public class UserSetting implements Serializable {
private String username;
private int gender; // 1=男, 0=女
private String qqNumber;
// 建構子、getter/setter 略
}
EditText username / qq_numberRadioGroup + 兩個 RadioButton (man/female) android:onClick="choiceGender"Button android:onClick="saveUserSetting"
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;
}
}
注意:Android 6.0+ (API 23) 需動態請求運行時權限,本範例為示範核心邏輯,實務上需補全 requestPermissions 流程。
| 方法 | 回傳路徑範例 | 說明 |
|---|---|---|
| getDataDirectory() | /data | 內部儲存根目錄 |
| getExternalStorageDirectory() | /storage/sdcard0 | 外部儲存(SD 卡)根目錄 |
| getDownloadCacheDirectory() | /cache | 下載快取 |
| getRootDirectory() | /system | 系統分區 |
serialVersionUID:建議顯式宣告,防止類別版本演進導致反序列化失敗。getExternalFilesDir() 專屬目錄,無需權限。