Android 4 学习(15):持久化:Files, Saving State and Preferences
参考《Professional Android 4 Development》
持久化:Files, Saving State and Preferences
Android中的数据持久化
1. Shared Preferences: 以键值对的形式存储,是一种轻量级的持久化方法。
2. Saved UI application state: Activities和Fragment的生命周期事件中会获得savedInstanceState参数,包含UI的内容。
3. Files。
使用Shared Preferences
SharedPreferences mySharedPreferences = getSharedPreferences(MY_PREFS, Activity.MODE_PRIVATE);
MODE_PRIVATE模式的Shared Preferences存储在应用程序的sandbox里面,其他应用程序无法访问。
修改Shared Preferences
SharedPreferences.Editor editor = mySharedPreferences.edit();
// Store new primitive types in the shared preferences object.
editor.putBoolean(“isTrue”, true);
editor.putFloat(“lastFloat”, 1f);
editor.putInt(“wholeNumber”, 2);
editor.putLong(“aNumber”, 3l);
editor.putString(“textEntryValue”, “Not Empty”);
// Commit the changes.
editor.apply()
读取Shared Preferences
可以获取单个属性的值:
// Retrieve the saved values.
boolean isTrue = mySharedPreferences.getBoolean(“isTrue”, false);
float lastFloat = mySharedPreferences.getFloat(“lastFloat”, 0f);
int wholeNumber = mySharedPreferences.getInt(“wholeNumber”, 1);
long aNumber = mySharedPreferences.getLong(“aNumber”, 0);
String stringPreference = mySharedPreferences.getString(“textEntryValue”, “”);
也可以将所有的键值对读到一个Map中:
Map<String, ?> allPreferences = mySharedPreferences.getAll();
检测Shared Preferences中是否含有某个属性的值:
boolean containsLastFloat = mySharedPreferences.contains(“lastFloat”);
Preference Framework
Android中的Preference Framework是基于XML的,其外观由主题决定,这样既可以使程序和系统保持一致的风格,又可以方便地继承其他程序的Preference。
Preference Framework包含四个部分:
1. Preference Screen Layout:用于定义Preference的显示,为XML文件。
2. Preference Activity和Preference Fragment:用于host Preference Screen,在Android3.0之前,使用Preference Activity;之后使用Preference Fragment。
3. Preference Header Definition:XML文件,定义Preference Fragment和显示他们的hierarchy。
4. Shared Preference Change Listener: OnSharedPreferenceChangeListener接口的实现类,监听Shared Preference的Change事件。
使用XML定义Preference Layout
定义Preference Layout的XML文件存放在res/xml文件夹下,下面是一个示例:
<?xml version=”1.0” encoding=”utf-8”?>
<PreferenceScreen xmlns:android=”http://schemas.android.com/apk/res/android”>
<PreferenceCategory android:title=”My Preference Category”>
<CheckBoxPreference android:key=”PREF_CHECK_BOX”
android:title=”Check Box Preference”
android:summary=”Check Box Preference Description”
android:defaultValue=”true”/>
</PreferenceCategory>
</PreferenceScreen>
效果图:
原生的Preference控件:
1. CheckBoxPreference
2. EditTextPreference
3. ListPreference
4. MultiSelectListPreference
5. RingtonePreference
使用Intent导入系统Preference
<?xml version=”1.0” encoding=”utf-8”?>
<PreferenceScreen xmlns:android=”http://schemas.android.com/apk/res/android”
android:title=”Intent preference”
android:summary=”System preference imported using an intent”>
<intent android:action=”android.settings.DISPLAY_SETTINGS “/>
</PreferenceScreen>
Preference Fragment简介
public class MyPreferenceFragment extends PreferenceFragment
重写onCreate()并调用addPreferencesFromResource方法,可以Inflate Preference Fragment。
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.userpreferences);
}
使用Preference Header定义Preference Fragment
Preference Header的XML文件位于res/xml目录下,每个Header的Resource ID是它的文件名(不含后缀)。
<preference-headers xmlns:android=”http://schemas.android.com/apk/res/android”>
<header android:fragment=”com.paad.preferences.MyPreferenceFragment”
android:icon=”@drawable/preference_icon”
android:title=”My Preferences”
android:summary=”Description of these preferences” />
</preference-headers>
和<PreferenceScreen>类似,<preference-headers>中也可以包含Intent:
<header android:icon=”@drawable/ic_settings_display”
android:title=”Intent”
android:summary=”Launches an Intent.”>
<intent android:action=”android.settings.DISPLAY_SETTINGS “/>
</header>
Preference Activity简介
创建Preference Activity:
public class MyFragmentPreferenceActivity extends PreferenceActivity
加载Preference Headers:
public void onBuildHeaders(List<Header> target) {
loadHeadersFromResource(R.xml.userpreferenceheaders, target);
}
对于早于3.0版本的系统,可以这样:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.userpreferences);
}
onSharedPreferenceChangeListener简介
实现onSharedPreferenceChangeListener接口,可以获得Preference的添加,修改和删除事件的callback。
public class MyActivity extends Activity implements OnSharedPreferenceChangeListener {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Register this OnSharedPreferenceChangeListener
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.registerOnSharedPreferenceChangeListener(this);
}
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
// TODO Check the shared preference and key parameters and change UI or behavior as appropriate.
}
}
Application Instance State持久化
使用Shared Preferences保存Activity State
// Create or retrieve the activity preference object.
SharedPreferences activityPreferences = getPreferences(Activity.MODE_PRIVATE);
// Retrieve an editor to modify the shared preferences.
SharedPreferences.Editor editor = activityPreferences.edit();
// Retrieve the View
TextView myTextView = (TextView)findViewById(R.id.myTextView);
// Store new primitive types in the shared preferences object.
editor.putString(“currentTextValue”,
myTextView.getText().toString());
// Commit changes.
editor.apply();
借助生命周期事件保存和恢复Activity Instance State
Activity提供了onSaveInstanceState handler来保存用户UI state等信息,其设计目标是当Activity被runtime terminate后,仍可以保存UI state信息。但如果Activity是被用户关闭或通过调用finish()方法关闭,则无法保存UI state信息。
private static final String TEXTVIEW_STATE_KEY = “TEXTVIEW_STATE_KEY”;
@Override
public void onSaveInstanceState(Bundle saveInstanceState) {
// Retrieve the View
TextView myTextView = (TextView)findViewById(R.id.myTextView);
// Save its state
saveInstanceState.putString(TEXTVIEW_STATE_KEY, myTextView.getText().toString());
super.onSaveInstanceState(saveInstanceState);
}
这个Handler提供了在用户session里面保存UI state的方法,跨用户session还是建议使用Shared Preference。
借助生命周期事件保存和恢复Fragment Instance State
Fragment的onCreate,onCreateView和onActivityCreated Handler会获得instance state bundle参数。Activity被销毁和重建时Fragment仍可以通过调用setRetainInstance方法保存自己。当Fragment调用setRetainInstance时,它将不会经历onDestroy和onCreate阶段。这样可以节省很多系统资源。
public class MyFragment extends Fragment {
private static String USER_SELECTION = “USER_SELECTION”;
private int userSelection = 0;
private TextView tv;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
if (savedInstanceState != null)
userSelection = savedInstanceState.getInt(USER_SELECTION);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.mainfragment, container, false);
tv = (TextView)v.findViewById(R.id.text);
setSelection(userSelection);
Button b1 = (Button)v.findViewById(R.id.button1);
Button b2 = (Button)v.findViewById(R.id.button2);
Button b3 = (Button)v.findViewById(R.id.button3);
b1.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
setSelection(1);
}
});
b2.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
setSelection(2);
}
});
b3.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
setSelection(3);
}
});
return v;
}
private void setSelection(int selection) {
userSelection = selection;
tv.setText(“Selected: “ + selection);
}
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putInt(USER_SELECTION, userSelection);
super.onSaveInstanceState(outState);
}
}
读写静态文件
静态文件可以放在res/raw目录下,作为资源使用。
Resources myResources = getResources();
InputStream myFile = myResources.openRawResource(R.raw.myfilename);
使用应用程序自己的文件夹存储文件
许多应用程序需要在自己的目录或其他目录中下载或创建文件。相应地,android提供了两个方法:getDir和getExternalFilesDir,分别用于在应用程序文件夹内部创建文件和在文件夹外部创建文件。
创建Private Application Files
String FILE_NAME = “tempfile.tmp”;
// Create a new output file stream that’s private to this application.
FileOutputStream fos = openFileOutput(FILE_NAME, Context.MODE_PRIVATE);
// Create a new file input stream.
FileInputStream fis = openFileInput(FILE_NAME);
上面代码默认的文件写模式为override,若要改为append,需将模式设为Context.MODE_APPEND。
若要将文件设为其他应用可写,可以使用Context.MODE_WORLD_WRITEABLE模式:
String OUTPUT_FILE = “publicCopy.txt”;
FileOutputStream fos = openFileOutput(OUTPUT_FILE, Context.MODE_WORLD_WRITEABLE);
获得应用的sandbox目录:
File file = getFilesDir();
Log.d(“OUTPUT_PATH_”, file.getAbsolutePath());
文件缓存
和普通文件一样,文件缓存也分为两种,内部缓存和外部缓存,分别使用getCacheDir和getExternalCacheDir获得。
常用的文件目录
- DIRECTORY_ALARMS
- DIRECTORY_DCIM
- DIRECTORY_DOWNLOADS
- DIRECTORY_MOVIES
- DIRECTORY_MUSIC
- DIRECTORY_NOTIFICATIONS
- DIRECTORY_PICTURES
- DIRECTORY_PODCASTS
- DIRECTORY_RINGTONES
如果这些默认值所对应的文件夹不存在,你可以自己去创建:
String FILE_NAME = “MyMusic.mp3”;
File path = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_MUSIC);
File file = new File(path, FILE_NAME);
try {
path.mkdirs();
[... Write Files ...]
} catch (IOException e) {
Log.d(TAG, “Error writing “ + FILE_NAME, e);
}
}
Android 4 学习(15):持久化:Files, Saving State and Preferences的更多相关文章
- Android开发学习之路--数据持久化之初体验
上班第一天,虽然工作上处于酱油模式,但是学习上依旧不能拉下,接着学习android开发吧,这里学习数据持久化的 知识. 其实数据持久化就是数据可以保存起来,一般我们保存数据都是以文件,或者数据库的形式 ...
- Android:日常学习笔记(9)———探究持久化技术
Android:日常学习笔记(9)———探究持久化技术 引入持久化技术 什么是持久化技术 持久化技术就是指将那些内存中的瞬时数据保存到存储设备中,保证即使在手机或电脑关机的情况下,这些数据仍然不会丢失 ...
- 我的Android 4 学习系列之文件、保存状态和首选项
目录 使用Shared Preference 保留简单的应用程序数据 保存回话间的Activity实例数据 管理应用程序首选项和创建Preference Screen 保存并加载文件以及管理本地文件系 ...
- Redis学习——Redis持久化之AOF备份方式保存数据
新技术的出现一定是在老技术的基础之上,并且完善了老技术的某一些不足的地方,新技术和老技术就如同JAVA中的继承关系.子类(新技术)比父类(老技术)更加的强大! 在前面介绍了Redis学习--Redis ...
- Android自动化学习笔记:编写MonkeyRunner脚本的几种方式
---------------------------------------------------------------------------------------------------- ...
- Android动画学习笔记-Android Animation
Android动画学习笔记-Android Animation 3.0以前,android支持两种动画模式,tween animation,frame animation,在android3.0中 ...
- Android开发学习总结(一)——搭建最新版本的Android开发环境
Android开发学习总结(一)——搭建最新版本的Android开发环境(转) 最近由于工作中要负责开发一款Android的App,之前都是做JavaWeb的开发,Android开发虽然有所了解,但是 ...
- android动画学习
android动画学习 转载自:http://www.open-open.com/lib/view/open1329994048671.html 3.0以前,android支持两种动画模式,twe ...
- Android Animation学习(二) ApiDemos解析:基本Animatiors使用
Animator类提供了创建动画的基本结构,但是一般使用的是它的子类: ValueAnimator.ObjectAnimator.AnimatorSet ApiDemos中Animation部分是单独 ...
随机推荐
- neutron ovs+vxlan
title: Neutron ovs+vxlan date: 2017-04-26 23:37 tags: Network 主机网卡配置 controller: ens160:192.168.11.1 ...
- HDU 3452 Bonsai(树形dp)
Bonsai Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) Total Submis ...
- springboot项目执行controller方法时进入慢的问题
今天在部署springboot项目到阿里云时,出现登录方法执行特别慢的问题.刚开始以为是卡死了,等了3,4分钟才进去,最后会出现如下信息: 2018-01-28 15:38:36.958 INFO 4 ...
- 【tensorflow:Google】四、深层神经网络
一.深度学习与深层神经网络 1.线性模型局限性 线性模型无论多少层,表达能力是一致的.可以通过激活函数实现非线性. 2.多层网络可以解决异或运算 二.损失函数定义 1.经典损失函数: 分类问题: 二分 ...
- selenium webdriver入门
写在前面:最近在研究UI自动化测试的过程中,发现公司里通常用的是AutomanX框架,而这个框架实际上是基于selenium webdriver框架的,所以在编写测试用例时,很多语法都是直接使用sel ...
- poj 3517
题目链接 http://poj.org/problem?id=3517 题意 约瑟夫环 要求最后删掉的那个人是谁: 方法 理解递推公式就行了 考虑这样一组数据 k ...
- 21天学通C++_Day1
被阿里实习生的第一轮电话面试刷掉以后,幡然醒悟,发现以前学习的C++基础一点都不扎实.为了把基础打扎实,重新学习一遍:为了让自己不放弃,也顺便可以把当天学到的东西记录下来,开始了写博客. 学习书籍:& ...
- RESTful 服务示例
WCF服务轻量级服务,可供JS调用 返回值格式:XML.Json 工程结构: 示例代码: using System; using System.Collections.Generic; using S ...
- SP104 HIGH - Highways
vjudge luogu 题意 就是要你求无向图的生成树个数.\(n\le 12\),保证答案不爆\(long long\). sol 矩阵树定理直接上. 如果怕掉精可以写整数意义下的高斯消元,需要辗 ...
- 关于JS浅拷贝和深拷贝
在 JS 中有一些基本类型像是Number.String.Boolean,而对象就是像这样的东西{ name: 'Larry', skill: 'Node.js' },对象跟基本类型最大的不同就在于他 ...