首先介绍数据持久化:指将那些内存中的瞬时数据保存到存储设备中,保证即使在手机或电脑关机的情况下,这些数据仍然不会丢失。保存在内存中的数据为瞬时数据,而保存在存储设备中的数据处于持久状态。
而持久化技术提供一个使数据在瞬时状态和持久状态之间转换的机制。
持久化技术主要分为三类:文件存储、SharedPreference存储以及数据库存储。还有一种不安全的存储方式–文件存在手机的sd卡中,它不如前三种方式操作简单而会带来安全隐患。
- 文件存储
首先看文件存储技术,主要通过Java流的方式来将一些简单的文本数据或二进制数据存储。
public void save(String input){
String data = "Data to save"
FileOutputStream out = null;
BufferedWriter writer= null;
try {
out = openFileOutput("data", Context.MODE_PRIVATE); //通过openFileOutput(命名,操作模式)方法来获得FileOutputStream的实例
writer = new BufferedWriter(new OutputStreamWriter(out));
//以FileOutputStream的实例构建一个OutputStreamWriter,然后以OutputStreamWriter来构建一个BufferedWriter的实例,通过BufferedWriter的write方法来写入数据
writer.write(data);
}catch (IOException e){
e.printStackTrace();
}finally {
try {
if (writer != null) {
writer.close(); //关闭输入流
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
- SharedPreferences存储
首先要获得SharedPreferences对象才能进行数据存储。
获得SharedPreferences对象的方法有三个,如下:
(1). public SharedPreferences getPreferences (int mode)
通过Activity对象获取,获取的是本Activity私有的Preference,保存在系统中的xml形式的文件的名称为这个Activity的名字,因此一个Activity只能有一个,属于这个Activity。
(2). public SharedPreferences getSharedPreferences (String name, int mode)
因为Activity继承了ContextWrapper,因此也是通过Activity对象获取,但是属于整个应用程序,可以有多个,以第一参数的name为文件名保存在系统中。
(3). public static SharedPreferences getDefaultSharedPreferences (Context context)
PreferenceManager的静态函数,保存PreferenceActivity中的设置,属于整个应用程序,但是只有一个,Android会根据包名和PreferenceActivity的布局文件来起一个名字保存。
如上记录了这三个方法的具体区别。
下面进行实例展示:
首先新建一个SharedPreferencesTest项目,修改activity_main.xml文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/save_data"
android:text="Save data"
android:textAllCaps="false"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/restore_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Restore"
android:textAllCaps="false"/>
</LinearLayout>
定义了两个Button按钮,一个表示保存数据,一个表示取出数据,下面是对这两个Button按钮的监听事件:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button save = (Button)findViewById(R.id.save_data);
save.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//这里的监听事件为保存数据,保存了三个不同类型的值,其他类型可以以此类推
SharedPreferences.Editor editor = getSharedPreferences("data",MODE_PRIVATE).edit();
editor.putString("name","Tom");
editor.putInt("age",28);
editor.putBoolean("married",false);
editor.apply();
}
});
Button restore = (Button)findViewById(R.id.restore_data);
restore.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//这里的监听事件为取出数据,取出三个数据,方法以此类推
//!!!在这里要注意保存和取出数据的方法不一样
SharedPreferences preferences = getSharedPreferences("data",MODE_PRIVATE);
String name = preferences.getString("name","");
boolean married = preferences.getBoolean("married",false);
int age = preferences.getInt("age",0);
Log.d(TAG, "name is "+name);
Log.d(TAG, "age is "+age);
Log.d(TAG, "married is "+married);
}
});
}
}
点击第一个Button按钮将保存数据,点击第二个Button按钮将在Android Monitor中打印如下:
07-13 05:44:18.412 6714-6714/com.example.sharedpreferencestest D/MainActivity: name is Tom
07-13 05:44:18.412 6714-6714/com.example.sharedpreferencestest D/MainActivity: age is 28
07-13 05:44:18.412 6714-6714/com.example.sharedpreferencestest D/MainActivity: married is false
借助SharedPreferences的特性可以实现记住密码功能:
首先借用广播的的一个项目BroadcastBestPractice,其activity_login.xml文件如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="horizontal">
<TextView
android:text="Account:"
android:textSize="20sp"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"/>
<EditText
android:id="@+id/edit_Account"
android:layout_width="0dp"
android:maxLines="1"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="horizontal">
<TextView
android:text="Passord:"
android:textSize="20sp"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"/>
<EditText
android:id="@+id/edit_Passord"
android:inputType="textPassword"
android:layout_width="0dp"
android:layout_weight="1"
android:maxLines="1"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<CheckBox
android:id="@+id/remember_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAllCaps="false"
android:text="Remember password"
android:textSize="20sp"/>
</LinearLayout>
<Button
android:id="@+id/btn_Login"
android:text="Login"
android:textSize="25sp"
android:textAllCaps="false"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
这个xml文件有点长,我们可以只看最后一个LinearLayout内置布局,其中一个TextView、一个CheckBox(复选框控件),这个内置布局表示是否记住用户账号与密码。
然后让我们看一下相对应的活动LoginActivity:
public class LoginActivity extends BaseActivity {
private SharedPreferences preferences;
private SharedPreferences.Editor editor;
private CheckBox rememberPassword;
private EditText Account;
private EditText Passord;
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
Account = (EditText)findViewById(R.id.edit_Account);
Passord = (EditText)findViewById(R.id.edit_Passord);
button = (Button)findViewById(R.id.btn_Login);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String account = Account.getText().toString();
String passord = Passord.getText().toString();
if (account.equals("abc") && passord.equals("123456")){
Intent intent = new Intent(LoginActivity.this,MainActivity.class);
startActivity(intent);
finish(); //在开启另一个活动时及时将被舍弃的活动销毁
editor = preferences.edit();
if (rememberPassword.isChecked()){ //检查复选框是否被选中
editor.putString("account",account);
editor.putString("password",passord);
editor.putBoolean("remember_password",true);
}else {
editor.clear();
}
editor.apply();
}else {
Toast.makeText(LoginActivity.this,"account or passord is invalid",Toast.LENGTH_SHORT).show();
}
}
});
preferences = PreferenceManager.getDefaultSharedPreferences(this);
rememberPassword = (CheckBox)findViewById(R.id.remember_password);
boolean isRemeber = preferences.getBoolean("remember_password",false);
if (isRemeber){
//将账号和密码都设置到文本框中
String account = preferences.getString("account","");
String password = preferences.getString("password","");
Account.setText(account);
Passord.setText(password);
rememberPassword.setChecked(true);
}
}
}
在这里,我们就看一下与本文有关的代码,这里的SharedPreferences 对象是通过PreferenceManager的getDefaultSharedPreferences()方法来获取的,这是第三种获取SharedPreferences 对象的方法(它属于整个应用程序并且只能有一个)。对于其中控件的实例化我们不加解释,我们看看最后面的if判断语句,条件中的
……………………我是分界线…………………………………………………………..
这里先撰写一点,后期会对数据库进行详解