实验目的
掌握SharedPreferences进行轻量级数据存储的方法;
实验要求
使用SharedPreferences保存用户登录信息;
使用SharedPreferences读取用户登录信息,并填充相应控件;
实验内容
步骤一,打开Code06项目
使用Android Studio打开Code06项目。
步骤二,新增CheckBox控件提供记住密码选项
为该项目添加一个CheckBox控件,用于向用户提供是否保存用户名密码的选项。当用户勾选该控件,并点击Login登录按钮时,将用户所填写的用户名、密码保存至SharedPreferences中,当用户下次启动App时,从指定的SharedPreferences文件中读取用户名、密码填充至相应的EditText控件中。App最终运行效果如图1. Code06新增记住用户名密码选项框所示。
1. 调整activity_login.xml布局文件
打开activity_login.xml文件,在密码EditText控件所在的RelativeLayout布局下方加入一个新的RelativeLayout布局,并在该布局中加入CheckBox控件。此外,还在该RelativeLayout中加入了一个TextView控件用于进行用户账号注册跳转使用,布局代码如下所示。
<RelativeLayout
...>
<EditText
android:id="@+id/et_pwd"
.../>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginTop="16dp">
<CheckBox
android:id="@+id/cb_remember_pwd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/colorPrimary"
android:layout_marginLeft="8dp"
android:text="Remember Password"
android:layout_marginBottom="4dp"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true"/>
<TextView
android:id="@+id/tv_sign_up"
android:text="Sign up"
android:textColor="@color/colorAccent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@id/cb_remember_pwd"
android:layout_marginEnd="8dp"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
步骤三,添加Login登录按钮保存用户账号及密码逻辑
当用户点击Login登录按钮时,App根据用户是否勾选Remember Password复选框决定是否将用户账号、密码等信息保存至SharedPreferences文件。
1. 定义SharedPreferences文件名等相关字符串资源
将需要操作的SharedPreferences文件名、保存的用户名、密码等Key存储于string.xml字符串资源中,有利于在App全局范围内维护这些信息。代码如下所示。
<resources>
<string name="app_name">LoginDemo</string>
<!-- Strings related to login -->
<string name="shared_preferences_file_name">sp_login
</string>
<string name="login_account_name">login_account_name
</string>
<string name="login_password">login_password
</string>
<string name="login_remember_password">login_remember_password
</string>
</resources>
2. 存储用户信息进SharedPreferences
在LoginActivity类的onCreate方法中首先获取用户名、密码、记住密码、登录等几个控件对应的对象。
public class LoginActivity extends AppCompatActivity
implements View.OnClickListener{
private EditText etPwd;
private EditText etAccount;
private CheckBox cbRememberPwd;
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
...
etPwd = findViewById(R.id.et_pwd);
etAccount = findViewById(R.id.et_account);
cbRememberPwd = findViewById(R.id.cb_remember_pwd);
Button btLogin = findViewById(R.id.bt_login);
...
}
}
当点击Login按钮时,检测cbRememberPwd按钮是否被勾选,如果被勾选则获得指定的SharedPreferences对象,并将用户名、密码保存进SharedPreferences中。如果未被勾选,则应该清除掉之前保存在SharedPreferences中的用户名、密码。
其中获取SharedPreferences对象文件名、用户名、密码Key的字符串资源使用Resources对象的getString()方法,该方法接收一个int型资源id, 可以使用R.string.XXXXX表示,其中XXXXX中为在string.xml文件中的定义的字符串资源名。
通过getSharedPreferences方法获得SharedPreferences对象,并通过SharedPreferences.Editor进行编辑操作。
public class LoginActivity extends AppCompatActivity
implements View.OnClickListener{
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
...
Button btLogin = findViewById(R.id.bt_login);
btLogin.setOnClickListener(this);
}
@Override
public void onClick(View view) {
String spFileName = getResources()
.getString(R.string.shared_preferences_file_name);
String accountKey = getResources()
.getString(R.string.login_account_name);
String passwordKey = getResources()
.getString(R.string.login_password);
String rememberPasswordKey = getResources()
.getString(R.string.login_remember_password);
SharedPreferences spFile = getSharedPreferences(
spFileName,
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = spFile.edit();
if (cbRememberPwd.isChecked()) {
String password = etPwd.getText().toString();
String account = etAccount.getText().toString();
editor.putString(accountKey, account);
editor.putString(passwordKey, password);
editor.putBoolean(rememberPasswordKey, true);
editor.apply();
} else {
editor.remove(accountKey);
editor.remove(passwordKey);
editor.remove(rememberPasswordKey);
editor.apply();
}
}
}
3. 读取SharedPreferences存储的用户账号信息
在Login按钮中对用户账号等数据存储入SharedPreferences或删除SharedPreferences中存储的用户账号数据。 而要加载SharedPreferences中存储的用户账号信息,最恰当的时机是在Activity的onCreate()方法中。
读取SharedPreferences中存储的键值对可使用getString()等方法,该方法第一个参数是键值对的key,第二个参数则为默认值。
public class LoginActivity extends AppCompatActivity
implements View.OnClickListener{
....
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
...
String spFileName = getResources()
.getString(R.string.shared_preferences_file_name);
String accountKey = getResources()
.getString(R.string.login_account_name);
String passwordKey = getResources()
.getString(R.string.login_password);
String rememberPasswordKey = getResources()
.getString(R.string.login_remember_password);
SharedPreferences spFile = getSharedPreferences(
spFileName,
MODE_PRIVATE);
String account = spFile.getString(accountKey, null);
String password = spFile.getString(passwordKey, null);
Boolean rememberPassword = spFile.getBoolean(
rememberPasswordKey,
false);
if (account != null && !TextUtils.isEmpty(account)) {
etAccount.setText(account);
}
if (password != null && !TextUtils.isEmpty(password)) {
etPwd.setText(password);
}
cbRememberPwd.setChecked(rememberPassword);
...
}
...
}
步骤四,编译、部署APK
编译并部署Code06项目的APK,运行效果如图1. Code06新增记住用户名密码选项框所示。 首先填入用户名及密码,并勾选记住密码复选框,点击Login登录按钮; 将App杀掉后,重新启动App观察启动后登录页面中的用户名、密码文本框是否进行了初始化设置。
SharedPreferences所存储的xml文件存放于设备的/data/data/[package_name]/shared_prefs目录下,其中package_name为App的包名。可以通过Android Studio中的Device File Explorer工具查看这些文件,如图2. Device file Explorer查看App私有数据所示。
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<boolean name="login_remember_password" value="true" />
<string name="login_password">1234567</string>
<string name="login_account_name">xgqin</string>
</map>
步骤五,将Code06项目代码及资源并入Code07
将Code06项目的代码资源并入Code07项目中,实现用户点击Login按钮后,跳转至新闻列表页。 其中需要合并的代码及资源包括:
mipmap-XXXX中的ic_logo.png等png图片
在Code07的AndroidManifest.xml文件中注册LoginActivity,并将其作为启动活动,代码如下所示。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.glriverside.xgqin.listviewdemo">
<application
...
android:theme="@style/AppTheme">
<activity android:name=".DetailActivity"></activity>
<activity android:name=".LoginActivity"
android:theme="@style/LoginTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivity">
</activity>
</application>
</manifest>
实验小结
通过本次实验,你应该掌握了如下知识内容:
使用SharedPreferences存取键值对数据;
清除SharedPreferences中存储的键值对数据;