Android中的状态保存-SharedPreferences和Bundle(文末小彩蛋)

本文介绍了Android中使用SharedPreferences进行数据持久化的详细步骤,包括获取SharedPreferences对象的三种方式以及如何存储和提交数据。同时,文章讨论了当活动被系统回收时,如何利用onSaveInstanceState()和onCreate()保存和恢复临时数据,以保证用户体验。此外,文末提到了在Genymotion模拟器上运行ARM程序的方法,涉及解决“INSTALL_FAILED_CPU_ABI_INCOMPATIBLE”错误的技巧。
摘要由CSDN通过智能技术生成

SharedPreferences 是使用键值对的方式来存储数据的。也就是说当保存一条数据的时候,需要给这条数据提供一个对应的键,这样在读取数据的时候就可以通过这个键把相应的值取出来。而且SharedPreferences 还支持多种不同的数据类型存储,如果存储的数据类型是整型,那么读取出来的数据也是整型的,存储的数据是一个字符串,读取出来的数据仍然是字符串。这样你应该就能明显地感觉到,使用SharedPreferences 来进行数据持久化要比使用文件方便很多,下面我们就来看一下它的具体用法吧。

将数据存储到SharedPreferences 中
要想使用SharedPreferences来存储数据,首先需要获取到SharedPreferences对象。Android中主要提供了三种方法用于得到SharedPreferences 对象。
1. Context 类中的getSharedPreferences()方法
此方法接收两个参数,第一个参数用于指定SharedPreferences 文件的名称,如果指定的文件不存在则会创建一个,SharedPreferences 文件都是存放在/data/data/<packagename>/shared_prefs/目录下的。第二个参数用于指定操作模式,主要有两种模式可以选择,MODE_PRIVATE 和MODE_MULTI_PROCESS。MODE_PRIVATE 仍然是默认的操作模式, 和直接传入0 效果是相同的, 表示只有当前的应用程序才可以对这个SharedPreferences 文件进行读写。MODE_MULTI_PROCESS 则一般是用于会有多个进程中对同一个SharedPreferences 文件进行读写的情况。类似地,MODE_WORLD_READABLE和MODE_WORLD_WRITEABLE 这两种模式已在Android 4.2 版本中被废弃。
2. Activity 类中的getPreferences()方法
这个方法和Context 中的getSharedPreferences()方法很相似,不过它只接收一个操作模式参数,因为使用这个方法时会自动将当前活动的类名作为SharedPreferences 的文件名。
3. PreferenceManager 类中的getDefaultSharedPreferences()方法这是一个静态方法,它接收一个Context 参数,并自动使用当前应用程序的包名作为前缀来命名SharedPreferences 文件。得到了SharedPreferences 对象之后,就可以开始向SharedPreferences 文件中存储数据了,
主要可以分为三步实现。
1. 调用SharedPreferences 对象的edit()方法来获取一个SharedPreferences.Editor 对象。
2. 向SharedPreferences.Editor 对象中添加数据,比如添加一个布尔型数据就使用
putBoolean 方法,添加一个字符串则使用putString()方法,以此类推。
3. 调用commit()方法将添加的数据提交,从而完成数据存储操作。

示例代码:

<span style="font-size:18px;">		SharedPreferences.Editor editor = getSharedPreferences("NetworkPara", MODE_PRIVATE).edit();
		editor.putBoolean("flagSend", flagSend);
		editor.commit();</span>

从SharedPreferences 中读取数据
你应该已经感觉到了,使用SharedPreferences 来存储数据是非常简单的,不过下面还有更好的消息,其实从SharedPreferences 文件中读取数据更加的简单。SharedPreferences 对象中提供了一系列的get方法用于对存储的数据进行读取,每种get方法都对应了SharedPreferences.Editor 中的一种put 方法,比如读取一个布尔型数据就使用getBoolean()方法,读取一个字符串就使用getString()方法。这些get 方法都接收两个参数,第一个参数是键,传入存储数据时使用的键就可以得到相应的值了,第二个参数是默认值,即表示当传入的键找不到对应的值时,会以什么样的默认值进行返回。

示例代码:

		SharedPreferences pref = getSharedPreferences("NetworkPara", MODE_PRIVATE);
		flagSend= pref.getBoolean("flagSend", true);
所有之前存储的数据都成功读取出来了!通过这个例子,我们就把SharedPreferences 存储的知识也学习完了。相比之下,SharedPreferences 存储确实要比文本存储简单方便了许多,应用场景也多了不少,比如很多应用程序中的偏好设置功能其实都使用到了SharedPreferences技术。



活动被回收了怎么办
前面我们已经说过,当一个活动进入到了停止状态,是有可能被系统回收的。那么想象以下场景,应用中有一个活动A,用户在活动A 的基础上启动了活动B,活动A 就进入了停止状态,这个时候由于系统内存不足,将活动A 回收掉了,然后用户按下Back 键返回活动A,会出现什么情况呢?其实还是会正常显示活动A 的,只不过这时并不会执行onRestart()方法,而是会执行活动A 的onCreate()方法,因为活动A 在这种情况下会被重新创建一次。这样看上去好像一切正常,可是别忽略了一个重要问题,活动A 中是可能存在临时数据和状态的。打个比方,MainActivity 中有一个文本输入框,现在你输入了一段文字,然后启动NormalActivity,这时MainActivity 由于系统内存不足被回收掉,过了一会你又点击了Back 键回到MainActivity,你会发现刚刚输入的文字全部都没了,因为MainActivity 被重新创建了。
如果我们的应用出现了这种情况,是会严重影响用户体验的,所以必须要想想办法解决这个问题。查阅文档可以看出,Activity 中还提供了一个onSaveInstanceState()回调方法,这个方法会保证一定在活动被回收之前调用,因此我们可以通过这个方法来解决活动被回收时
临时数据得不到保存的问题。onSaveInstanceState()方法会携带一个Bundle 类型的参数,Bundle 提供了一系列的方法用于保存数据,比如可以使用putString()方法保存字符串,使用putInt()方法保存整型数据,以此类推。每个保存方法需要传入两个参数,第一个参数是键,用于后面从Bundle 中取值,第二个参数是真正要保存的内容。

示例代码:

	@Override
	public void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		outState.putBoolean("flagSend",flagSend);
		Log.d(TAG, "outState.putBoolean(\"flagSend\",flagSend)" + flagSend);
	}


数据是已经保存下来了,那么我们应该在哪里进行恢复呢?细心的你也许早就发现,我们一直使用的onCreate()方法其实也有一个Bundle 类型的参数。这个参数在一般情况下都是null,但是当活动被系统回收之前有通过onSaveInstanceState()方法来保存数据的话,这个参数就会带有之前所保存的全部数据,我们只需要再通过相应的取值方法将数据取出即可。修改MainActivity 的onCreate()方法,如下所示:

示例代码:

		if(savedInstanceState != null){
			flagSend = savedInstanceState.getBoolean("flagSend");
			Log.d(TAG, "savedInstanceState.getBoolean(\"flagSend\")" + flagSend);
			if(flagSend){
				isShowSend_iv_networkpara.setBackgroundResource(R.drawable.ucar_check);
			}else {
				isShowSend_iv_networkpara.setBackgroundResource(R.drawable.ucar_uncheck);
			}
		}


文末小彩蛋

 

Android模拟器Genymotion添加ARM程序运行环境的方法

 

搞开发也很多年了,还是第一次写blog,给自己留一些记录吧

自从用了Genymotion这个号称快到极致的Android模拟器以后,很多时候调试程序都不想用真机了,SDK带效率低下的官方模拟器因为效率太低也放弃了(据说可以通过配置来改进一直没去尝试过)

通过模拟器和hierarchyviewer可以很方便查看很多程序的界面布局,用于学习非常不错,不过也一直有个问题,就是很多ARM的程序都没法安装(比如微信),毕竟是用的vbox虚拟机,相当于在x86环境下运行的,限定ARM的程序自然是无法安装了,会提示"INSTALL_FAILED_CPU_ABI_INCOMPATIBLE"这个错误,无法向模拟器部署,如果直接安装APK则会提示与您的设备不兼容。

那么是不是就没有办法了呢?通过查找资料,发现了解决的方法,相信很多人也早就知道了,参考xda的这篇文章:

http://forum.xda-developers.com/showthread.php?t=2528952

使用方法也很简单,就是将zip文件直接拖放到Genymotion的player窗口中即可自动安装(安装后要重启一次)。

不过在实际操作的过程中,发现在部分模拟器环境下,将zip文件拖进去以后会报错,提示"an error occurred while deploying a file"。经过实验,用DDMS也没法手动安装zip包里的东西(要复制到system下)。个人认为原因可能在于设备没有在root的状态下,但是Genymotion应该是已经root了的啊,最后解决方法是通过re管理器之类的文件管理工具,先获得root的读写权限,然后将文件手动复制过去替换就行了(记得要重启)。其实这方法也是xda的帖子里面提到的。应该还有更简单的方法,其实就是将zip包中的system/lib下的文件都复制到设备就行了。

这么操作以后,就可以安装各种ARM的程序了,微信也正常安装,经测试使用也没有什么问题。

没试过Genymotion的朋友推荐试试这个模拟器,很多时候,比真机要更快捷方便,性能也很棒

安兔兔测试,不能跑3D测试部分,不过分数还是不错的...

 

Android应用权限

Android应用需要在AndroidManifest.xml添加某些权限。才能调用系统功能。如应用提供震动功能。必须在配置文件中加入震动权限。

 

属性

说明

android.permission.ACCESS_CHECKIN_PROPERTIES

允许读写访问 "properties"表在checkin数据库中,改值可以修改上传

android.permission.ACCESS_COARSE_LOCATION

通过WiFi或移动基站的方式获取用户错略的经纬度信息,定位精度大概误差在30~1500米

android.permission.ACCESS_FINE_LOCATION

通过GPS芯片接收卫星的定位信息,定位精度达10米以内

android.permission.ACCESS_LOCATION_EXTRA_COMMANDS

允许应用程序访问额外的位置提供命令

android.permission.ACCESS_MOCK_LOCATION

获取模拟定位信息,一般用于帮助开发者调试应用

android.permission.ACCESS_NETWORK_STATE

获取网络信息状态,如当前的网络连接是否有效

android.permission.ACCESS_SURFACE_FLINGER

Android平台上底层的图形显示支持,一般用于游戏或照相机预览界面和底层模式的屏幕截图

android.permission.ACCESS_WIFI_STATE

允许程序访问Wi-Fi网络状态信息

android.permission.ACCOUNT_MANAGER

获取账户验证信息,主要为GMail账户信息,只有系统级进程才能访问的权限

android.permission.AUTHENTICATE_ACCOUNTS

允许一个程序通过账户验证方式访问账户管理ACCOUNT_MANAGER相关信息

android.permission.ADD_SYSTEM_SERVICE

允许程序发布系统级服务

android.permission.BATTERY_STATS

允许程序更新手机电池统计信息

android.permission.BIND_APPWIDGET

允许一个程序告诉appWidget服务需要访问小插件的数据库,只有非常少的应用才用到此权限

android.permission.BIND_DEVICE_ADMIN

请求系统管理员接收者receiver,只有系统才能使用

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值