一、持久化技术简介
1. 瞬时数据:
存储在内存中,当内存被回收时,会丢失的数据。
2. 数据持久化:
将内存中的瞬时数据保存到存储设备中,保证设备关机后,数据不会丢失。
3. Android中的三种实现数据持久化功能的技术:
A. 文件存储 B. SharedPreference 存储 C. 数据库存储
二、文件存储
最基本的一种数据存储方式,不对所存储的数据进行任何的格式化处理,适合一些简单的文本数据或者二进制数据。
核心技术:Context 类中提供的 openFileInput(…) 和 openFileOutput(…) 方法,配合上Java的各种流来进行读写操作。
1. 存储数据到文件中
Context 类中提供的 openFileOutput(…) 方法:
openFileOutput(…)
参数一: 文件名,不可以包含路径(文件默认存储到/data/data//files/目录下)
参数二: 文件的操作模式,模式一:MODE_PRIVATE(默认)同名时覆盖原文件;模式二:MODE_APPEND 同名时追加内容。
返回值: FileOutputStream 对象
2. 从文件中读取数据
Context 类中提供的 openFileInput(…) 方法:
openFileInput(…)
参数: 文件名
返回值: FileInputStream 对象
三、SharedPreferences 存储
使用键值对存储数据,支持多种不同的数据类型存储。使用XML格式来对数据进行管理。
1. 将数据存储到 SharedPreferences 中
步骤:
- 获取SharedPreferences对象;
- 调用SharedPreferences对象的edit()方法获得SharedPreferences.Editor对象;
- 向SharedPreferences.Editor对象添加数据,使用方法putXxx(K,V);(Xxx 某数据类型;K 键名;V 值);
- 调用apply()方法,将添加的数据提交。
如何获取到SharedPreferences对象呢?Android主要提供了三种方法:
- Context类 getSharedPreferences(…)方法
参数一: 文件名(文件默认存到/data/data//shared_prefs/目录下)
参数二: 操作模式,MODE_PRIVATE(默认)和直接传入0的效果相同,表只有当前应用程序可以对此SharedPreferences文件进行读写。
返回值: SharedPreferences 对象; - Activity类 getPreferences(…)方法
参数: 操作模式;
返回值: SharedPreferences 对象;
该方法会自动将当前活动的类名作为SharedPreferences的文件名。 - PreferenceManager类 getDefaultSharedPreferences(…)静态方法
参数: Context对象;
返回值: SharedPreferences 对象;
该方法会自动使用当前应用程序的包名作为前缀来命名SharedPreferences文件。
2. 从 SharedPreferences 中读取数据
方法: 调用SharedPreferences提供的方法getXxx(…)方法
参数一: K键;
参数二: 默认值;(当传入的键找不到对应的值,以这个默认值返回)
3. 实现记住密码功能
这只是一个简单的示例,并不能在实际项目中直接使用,因为这种将密码以明文的形式存储在SharedPreferences文件中是非常不安全的,易被盗取,在正式的项目中还需要配合加密算法来对密码进行保护。
A. 在此项目上进行修改广播的最佳实践——实现强制下线功能
B. 效果图
1.)登录界面
2.)输入账号密码并勾选记住密码
3.)强制重新登陆
C. 代码
1.)activity_login.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.thinkpad.broadcastbestpractice.LoginActivity">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="60dp">
<TextView
android:layout_width="90dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textSize="18sp"
android:text="账号:"/>
<EditText
android:id="@+id/account"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center_vertical"/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="60dp">
<TextView
android:layout_width="90dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textSize="18sp"
android:text="密码:"/>
<EditText
android:id="@+id/password"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:inputType="textPassword"/>
</LinearLayout>
<!--复选框的布局-->
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<CheckBox
android:id="@+id/remember_pass"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:text="记住密码!"/>
</LinearLayout>
<Button
android:id="@+id/login"
android:layout_width="match_parent"
android:layout_height="60dp"
android:text="登录"/>
</LinearLayout>
2.)LoginActivity.java
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;
public class LoginActivity extends BaseActivity {
private SharedPreferences pref; //SharedPreferences 变量
private SharedPreferences.Editor editor; //SharedPreferences.Editor变量
private EditText accountEdit; //输入账号的EditText变量
private EditText passwordEdit; //输入密码的EditText变量
private Button login; //登录按钮变量
private CheckBox rememberPass; //复选框变量
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
pref = PreferenceManager.getDefaultSharedPreferences(this);//获取pref实例
//实例化控件
accountEdit = (EditText)findViewById(R.id.account);
passwordEdit = (EditText)findViewById(R.id.password);
rememberPass = (CheckBox)findViewById(R.id.remember_pass);
boolean isRemember = pref.getBoolean("remember_password",false);//获取复选框先前状态
if(isRemember){
//如果复选框先前被选中,那么将账号密码从SharedPreferences文件中读出,设置到文本框中
String account = pref.getString("account","");
String password = pref.getString("password","");
accountEdit.setText(account);
passwordEdit.setText(password);
rememberPass.setChecked(true);
}
login = (Button)findViewById(R.id.login);
//为登陆按钮设置点击事件
login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String account = accountEdit.getText().toString(); //获取账号输入框中的内容
String password = passwordEdit.getText().toString(); //获取密码输入框中的内容
//判断账号密码是否正确;此处的账号:Nicholas 密码: hzf
if (account.equals("Nicholas")&&password.equals("hzf")){
editor = pref.edit(); //获取SharedPreferences.Editor实例
if(rememberPass.isChecked()){
//查看复选框是否被选中,若选中则将文本框中的信息存入SharedPreferences文件中
editor.putBoolean("remember_password",true);//存入当前复选框状态
editor.putString("account",account);
editor.putString("password",password);
}else{
editor.clear();//未被选中则将文件内容清空
}
editor.apply();//提交数据
Intent intent = new Intent(LoginActivity.this,MainActivity.class);
startActivity(intent);
finish();
}else{
Toast.makeText(LoginActivity.this,"账号密码输入错误或者为空!",Toast.LENGTH_SHORT).show();
}
}
});
}
}