Android Developers:保存键-值对

本文介绍了如何使用SharedPreferences API在Android应用程序中保存和检索简单的键值对数据。包括如何获取SharedPreferences实例、写入数据以及读取数据。

如果你有一个相对小的键值对集合需要保存,你应该使用SharedPreferencesAPIs。一个SharedPreferences对象指向一个包含键值对的文件,并提供简单的方法来读和写它们。每个SharedPreferences文件通过框架被管理,并可以私有化或者被共享.

这节课程向你展示了如何使用SharedPreferencesAPI保存和获取简单的值.

注意:SharedPreferencesAPIs仅仅用于读取和写入键-值对,并且你不应该把它和PreferenceAPI混淆,它帮助你为你的应用程序构建一个用户设置界面(尽管它们使用SharedPreferences实现应用程序设置的保存).更多关于使用PreferenceAPIs的实现,请查阅Setting指南.

获取一个SharedPreferences句柄

—————————————————————————————————————————————

通过调用下面两个方法之一,你能创建一个新的共享参数文件,或这访问一个已经存在的

  • getSharedPreferences() -如果你需要多个过名字标识的共享参数文件,使用这个方法,你使用第一个参数指定名字。你能在你应用中的任何Context调用它.

  • getPreference() - 如果你仅仅需要这个Activity的一个共享参数文件,在这个Activity中使用这个方法。因为它返回一个默认的共享参数文件,它属于这个Activity,你不需要提供一个名字

例如,下面的代码是在一个Fragment中被执行。它访问了通过字符串资源R.string.preference_file_key识别的共享参数文件,并且使用私有模式打开它,所以文件仅仅允许你的应用程序访问.

Context context = getActivity(); 
SharedPreferences sharedPref = context.getSharedPreferences( 
        getString(R.string.preference_file_key), Context.MODE_PRIVATE); 

当命名你的共享参数文件的时候,你应该使用一个在你的应用中唯一标识,如”com.example.myapp.PREFERENCE_FILE_KEY”.

另外,如果你仅仅需要你的Activity的一个共享参数文件,你能使用getPreferences()方法:

SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE); 
写入SharedPreferences

——————————————————————————————————————————————

为了写一个共享参数文件,通过调用一个SharedPreferences的edit()创建一个SharedPreferences.Editor.

使用入putInt()和putString()方法传递你想写入的键和值.然后调用commit()方法保存改变.例如:

SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE); 
SharedPreferences.Editor editor = sharedPref.edit(); 
editor.putInt(getString(R.string.saved_high_score), newHighScore); 
editor.commit(); 
读取SharedPreferences

——————————————————————————————————————————————

为了从一个sharedpreferences文件中获取一个值,调用如getInt()方法和getString()方法,提供你想要的键的值,并且如果键不存在,选择返回一个默认的值。例如:

SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE); 
int defaultValue = getResources().getInteger(R.string.saved_high_score_default); 
long highScore = sharedPref.getInt(getString(R.string.saved_high_score), defaultValue); 


<think>我们正在处理Android开发中的两个问题: 1. 使用被弃用的API 2. 避免使用`android:screenOrientation="portrait"`来固定活动方向 首先,关于使用被弃用的API: 在Android开发中,API会被不断更新和替换。当某个API被弃用时,意味着它不再被推荐使用,并且在未来的版本中可能会被移除。因此,我们需要替换弃用的API为新的替代方案。 其次,关于固定活动方向: 在AndroidManifest.xml中,我们通常使用`android:screenOrientation`属性来固定活动的方向(如竖屏portrait)。但是,在某些情况下,我们可能希望避免固定方向,而是让活动能够根据设备的方向进行旋转,或者通过其他方式处理方向变化。 然而,用户的问题似乎是希望避免限制活动为固定方向(即不希望使用portrait固定),同时又要处理使用弃用API的问题。但注意,用户的问题描述中,他既想解决弃用API的问题,又想避免固定方向。 但是,请注意:`android:screenOrientation`属性并没有被弃用,它仍然是一个有效的属性。所以这里可能有两个独立的问题: 1. 如何替换弃用的API(但用户没有具体说明是哪些弃用的API,所以我们需要一般性的指导)。 2. 如何避免使用`android:screenOrientation`来固定方向(即允许旋转),同时正确处理配置变化。 下面我们分别讨论: ### 问题1: 替换被弃用的API 由于用户没有具体说明是哪些API被弃用,我们给出一般性步骤: - 识别弃用的API:在Android Studio中,弃用的API通常会以删除线显示或产生警告。 - 查看官方文档:每个弃用的API通常都会有替代方案,官方文档会说明应该使用哪个新API替换。 - 使用兼容库:有时新的API在旧版本Android上不可用,可以使用AndroidX兼容库中的类和方法。 例如,在Activity中,`onActivityResult`方法被弃用,替代方案是使用Activity Result API(如`registerForActivityResult`)。 ### 问题2: 避免固定活动方向,且正确处理配置变化 如果不想固定方向(即允许旋转),那么就不要在AndroidManifest.xml中设置`android:screenOrientation`属性,或者将其设置为`sensor`(根据传感器决定方向)等。 但是,当屏幕旋转时,默认情况下Activity会销毁并重新创建。如果我们不希望Activity被重新创建,或者希望在旋转时保存状态,我们可以通过以下方式处理: 方法一:在AndroidManifest.xml中为Activity配置`configChanges`属性,然后在Activity中重写`onConfigurationChanged`方法。 例如: 在AndroidManifest.xml中: ```xml <activity android:name=".MyActivity" android:configChanges="orientation|screenSize"/> ``` 然后在Activity中: ```java @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); // 在这里处理方向变化,例如更新布局等 } ``` 方法二:如果你想在旋转时保存某些数据,可以使用ViewModel或者通过`onSaveInstanceState`保存状态,然后在`onCreate`或`onRestoreInstanceState`中恢复。 但是,请注意,官方推荐的做法是让应用能够适应配置变更(即允许重建并恢复状态),而不是阻止重建。因为阻止重建可能会带来其他问题,而且并不是所有的配置变更都可以通过`configChanges`处理。 不过,用户的要求是“避免限制活动为固定方向”,所以我们只需要不设置`screenOrientation`即可。同时,如果用户不希望活动在旋转时重建,则可以使用`configChanges`。 但是,用户的问题描述中提到了“避免限制活动为固定方向”,所以核心是不要设置`screenOrientation`为`portrait`,而是允许旋转。至于如何处理旋转,可以选择让系统重建活动(默认行为)或者通过`configChanges`自行处理。 总结: 1. 替换弃用API:需要具体问题具体分析,一般步骤是识别弃用API并查找官方推荐替代方案。 2. 避免固定方向:从清单文件中移除`android:screenOrientation="portrait"`,然后根据需求选择是否处理配置变更(默认重建活动,或者使用`configChanges`自行处理)。 由于用户没有提供具体的弃用API,我们无法给出具体的替换代码。但我们可以给出关于方向处理的具体代码示例。 示例:允许活动旋转并处理配置变更(不重建活动) 在AndroidManifest.xml中: ```xml <activity android:name=".MyActivity" android:configChanges="orientation|screenSize|keyboardHidden" /> ``` 在Activity中: ```java public class MyActivity extends AppCompatActivity { // ... @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); // 检查方向变化 if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { // 横屏时的操作,例如调整布局 } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) { // 竖屏时的操作 } } } ``` 注意:从Android 3.2(API level 13)开始,屏幕旋转时不仅会改变orientation,还会改变screenSize(因为旋转可能改变可用屏幕尺寸),所以需要同时监听`orientation|screenSize`。 但是,官方并不推荐使用`configChanges`来处理所有的配置变更,因为这样需要手动调整布局,容易出错。更好的做法是让系统重建Activity,然后通过保存和恢复状态(例如使用ViewModel)来保持数据。 因此,更推荐的做法是: - 移除`android:screenOrientation`属性(允许旋转) - 不在清单文件中设置`configChanges`,让系统重建Activity - 使用ViewModel来保存数据,这样在重建时数据不会丢失。 例如,使用ViewModel: ```java public class MyViewModel extends ViewModel { // 保存需要的数据 } ``` 在Activity中: ```java public class MyActivity extends AppCompatActivity { private MyViewModel viewModel; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); viewModel = new ViewModelProvider(this).get(MyViewModel.class); // 使用viewModel中的数据初始化UI } } ``` 这样,即使屏幕旋转导致Activity重建,ViewModel中的数据依然会被保留。 所以,对于用户的问题: - 避免固定方向:移除`android:screenOrientation`属性。 - 处理旋转:推荐使用ViewModel保存数据,允许系统重建Activity。 同时,对于弃用API的问题,需要用户提供具体是哪些API,然后才能给出替换方案。 如果用户没有提供具体弃用的API,我们可以提醒用户检查代码中的警告,并查阅官方文档更新API。 因此,回答如下: 针对您的问题: 1. **解决使用被弃用API的问题**: 由于您未提供具体的弃用API,我无法给出精确的替换方案。但通常,您可以按照以下步骤操作: -Android Studio中,查看代码中的警告(有删除线的代码即为弃用API)。 - 查阅Android官方文档,了解该API的替代方案。 - 使用推荐的替代API进行替换。如果新API需要兼容旧版本,请检查API级别并使用兼容库(如AndroidX)。 例如,如果您使用的是已经被弃用的`getDrawable(int id)`方法,您应该使用`ContextCompat.getDrawable(context, id)`代替。 2. **避免固定活动方向(即避免使用`android:screenOrientation="portrait"`)并处理屏幕旋转**: 您可以移除AndroidManifest.xml中Activity的`android:screenOrientation`属性(或设置为`sensor`等非固定),这样活动就可以根据设备方向旋转。 但是,旋转屏幕会导致活动默认重建。为了处理重建,推荐使用以下方法: - **使用ViewModel保存数据**:ViewModel可以在配置更改(如屏幕旋转)后仍然保留数据,确保数据不丢失。 - **使用`onSaveInstanceState`保存轻量数据**:对于少量数据(如UI状态),您可以通过重写`onSaveInstanceState`保存,然后在`onCreate`或`onRestoreInstanceState`中恢复。 **不推荐**使用`android:configChanges`来避免重建活动,因为这样需要手动处理布局调整,可能会增加代码复杂性,而且官方推荐让系统重建活动。 如果您仍然希望自行处理配置变更(不重建活动),可以在清单文件中为Activity添加: ```xml android:configChanges="orientation|screenSize" ``` 并在Activity中重写`onConfigurationChanged`方法,但这种方法需要您自己调整布局,因此请谨慎使用。 综上所述,我建议: - 移除`android:screenOrientation`属性以允许旋转。 - 使用ViewModel和`onSaveInstanceState`来处理屏幕旋转时的数据保存,让系统重建活动。 这样,您的应用将能够适应屏幕旋转,并且避免了使用固定方向。 如果您有具体的弃用API需要帮助替换,请提供详细信息,我会给出具体的代码示例。 §§相关问题§§ 1. 如何检查代码中使用了哪些被弃用的API? 2. 在Android中,ViewModel是如何在屏幕旋转时保存数据的? 3. 除了屏幕旋转,还有哪些常见的设备配置变更需要处理? </think>针对您的问题,我将分两部分解答:解决使用弃用API的问题和避免强制固定屏幕方向的方法。 ### 一、解决使用弃用API的问题 1. **识别弃用API** -Android Studio中,弃用API会显示删除线警告(如:~~requestPermissions()~~) - 使用Lint工具扫描:`Analyze > Inspect Code`[^1] - 官方迁移指南:访问Android Developers网站的[API差异报告](https://developer.android.com/sdk/api_diff) 2. **常见弃用API及替代方案** | 弃用API | 替代方案 | 使用场景 | |---------|---------|----------| | `startActivityForResult()` | `Activity Result API` | 启动带回调的Activity | | ~~BluetoothAdapter.getDefaultAdapter()~~ | `BluetoothManager.getAdapter()` | 蓝牙管理 | | ~~AsyncTask~~ | `kotlin协程`或`WorkManager` | 后台任务 | ```kotlin // 新Activity Result API示例 val launcher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> if (result.resultCode == RESULT_OK) { // 处理返回数据 } } launcher.launch(Intent(this, NewActivity::class.java)) ``` 3. **兼容性处理** ```java if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { // 使用新API window.insetsController?.hide(Type.systemBars()); } else { // 旧版本回退方案 getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN); } ``` ### 二、避免强制固定屏幕方向 1. **移除固定方向声明** 从AndroidManifest中删除`android:screenOrientation="portrait"`: ```xml <activity android:name=".MainActivity" <!-- 删除此行:android:screenOrientation="portrait" --> /> ``` 2. **动态处理屏幕旋转(两种方案)** **方案一:允许旋转并自动重建(推荐)** ```kotlin class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // ViewModel将保持数据一致性 val viewModel: MainViewModel by viewModels() } } ``` - 配合`ViewModel`和`onSaveInstanceState()`保存数据 - 使用`android:configChanges`**不推荐**,会引入兼容性问题 **方案二:动态锁定方向(按需)** ```kotlin // 临时锁定为竖屏 requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT // 恢复自动旋转 requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED ``` 3. **处理盘弹出等配置变更** ```xml <activity android:name=".LoginActivity" android:windowSoftInputMode="adjustResize|stateVisible" /> ``` - `adjustResize`:调整布局避免盘遮挡 - `adjustPan`:平移窗口内容 ### 三、最佳实践总结 1. 使用`AndroidX`库确保API兼容性 2. 屏幕方向: - 默认允许旋转 - 使用`ViewModel`保持数据状态 - 仅在特定场景(如视频播放)动态锁定方向 3. 定期使用`./gradlew lint`检查弃用API[^1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值