1.SharedPreferences
1.1SharedPreferences简介
-
SharedPreferences 是 Android 系统提供的一个通用的数据持久化框架,用于存储和读取 key-value 类型的原始基本数据对。
-
目前仅支持 boolean、float、int、long 和 string 等基本类型的存储,对于自定义的复合数据类型,是无法使用 SharedPreferences 进行存储的。
-
SharedPreferences 主要用于存储系统的配置信息,类似于 Windows 下常用的 .ini 文件。
-
例如上次登录的用户名、上次最后设置的信息等,通过保存上一次用户所做的修改或者自定义参数设定,当再次启动程序后依然保持原有设置。它是用键值对的方式存储的,方便管理写入和读取。
1.2如何使用呢?
1.获取SharedPreferences对象
每个 Activity 默认都有一个 SharedPreferences 对象,获取 SharedPreferences 对象的方法有两种:
1)SharedPreferences getSharedPreferences(String name, int mode)。
使用该方法获取 name 指定的 SharedPreferences 对象,并获取对该 SharedPreferences 对象的读写控制权。
当应用程序中可能使用到多个 SharedPreferences 时使用该方法。
SharedPreferences sp = getSharedPreferences("login",MODE_PRIVATE);
2)SharedPreferences getPreferences(int mode)。
当应用程序中仅需要一个SharedPreferences对象时,使用该方法获取当前 Activity 对应的 SharedPreferences,而不需要指定 SharedPreferences 的名字。
SharedPreferences sp1 = getPreferences(MODE_PRIVATE);
其中,参数 mode 有 4 种取值,分别是:
-
MODE_PRIVATE:默认方式,只能被创建的应用程序或者与创建的应用程序具有相同用户 ID 的应用程序访问。
-
MODE_WORLD_READABLE:允许其他应用程序对该 SharedPreferences 文件进行读操作。
-
MODE_WORLD_WRITEABLE:允许其他应用程序对该 SharedPreferences 文件进行写操作。
-
MODE_MULTI_PROCESS:在多进程应用程序中,当多个进程都对同一个 SharedPreferences 进行访问时,该文件的每次修改都会被重新核对。
2.获取 SharedPreferences.Editor
调用 edit() 方法获取 SharedPreferences.Editor,SharedPreferences 通过该接口对其内容进行更新。
SharedPreferences.Editor editor = sp.edit();
3.更新 SharedPreferences
-
通过 SharedPreferences.Editor 接口提供的 put 方法对 SharedPreferences 进行更新。
例如使用 putBoolean(String key, boolean value)、putFloat(String key, float value) 等方法将相应数据类型的数据与其 key 对应起来
editor.putString("user",user);
editor.putString("pwd",pwd);
4.提交
调用 SharedPreferences.Editor 的 commit() 方法将更新提交到 SharedPreferences 中。
editor.commit();
1.3具体使用场景
当用户在该实例运行时,在文本框中输入电话号码和所在城市,例如 13800000000 和 beijing,单击回退按钮退出应用程序时,该应用程序将相关信息写入其对应的 SharedPreferences 中。实现效果如下:
-
当用户再次启动该应用程序时,之前填写到文本框内的信息会被从 SharedPreferences 中读取并显示出来,以方便用户修改。
代码实现:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="使用 Shared Preferences 存储程序信息" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="您的电话号码" />
<EditText
android:id="@+id/phone_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="输入电话号码" />
<EditText
android:id="@+id/city_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="输入城市名称" />
</LinearLayout>
MainActivity.java
package com.hopu.demo;
import androidx.appcompat.app.AppCompatActivity;
import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.widget.EditText;
public class MainActivity extends AppCompatActivity {
private EditText phoneText, cityText;
private String phone, city;
public static final String SET_INFO = "SET_Info";
public static final String PHONE = "PHONE";
public static final String CITY = "CITY";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
phoneText = (EditText) findViewById(R.id.phone_text);
cityText = (EditText) findViewById(R.id.city_text);
/*获取Shared Preferences对象*/
SharedPreferences setinfo = getPreferences(Activity.MODE_PRIVATE);
/*取出保存的电话号码和地址信息*/
phone = setinfo.getString(PHONE, "");
city = setinfo.getString(CITY, "");
/*将取出的信息分别放在对应的EditText中*/
phoneText.setText(phone);
cityText.setText(city);
}
@Override
protected void onStop() {
SharedPreferences setinfo = getPreferences(Activity.MODE_PRIVATE);
setinfo.edit()
.putString(PHONE, phoneText.getText().toString())
.putString(CITY, cityText.getText().toString())
.commit();
super.onStop();
}
}
2.什么是SQLite
2.1SQLite简介
SQLite是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。它是一个零配置的数据库,这意味着与其他数据库不一样,您不需要在系统中配置。就像其他数据库,SQLite 引擎不是一个独立的进程,可以按应用程序需求进行静态或动态连接。SQLite 直接访问其存储文件。
2.2SQLite的优势
-
不需要一个单独的服务器进程或操作的系统(无服务器的)。
-
SQLite 不需要配置,这意味着不需要安装或管理。
-
一个完整的 SQLite 数据库是存储在一个单一的跨平台的磁盘文件。
-
SQLite 是非常小的,是轻量级的,完全配置时小于 400KiB,省略可选功能配置时小于250KiB。
-
SQLite 是自给自足的,这意味着不需要任何外部的依赖。
-
SQLite 事务是完全兼容 ACID 的,允许从多个进程或线程安全访问。
-
SQLite 支持 SQL92(SQL2)标准的大多数查询语言的功能。
-
SQLite 使用 ANSI-C 编写的,并提供了简单和易于使用的 API。
-
SQLite 可在 UNIX(Linux, Mac OS-X, Android, iOS)和 Windows(Win32, WinCE, WinRT)中运行。
综合来看,即轻量 兼容 多端 无需配置 无外部依赖 拥有简单易懂的API 安全
2.3使用SQLite使用
1.创建数据库
创建DBHelper.java
让创建的DBHelper继承SQLiteOpenHelper
继承的抽象类SQLiteOpenHelper中的两个抽象方法
创建带全部参数的DBHelper类的构造函数以便于生成数据库对象
2.生成数据库
我们给数据库起名为“info.db”,数据库版本号为1,需要对构造方法进行修改。代码如下
public DBHelper(@Nullable Context context) {
super(context, "info.db", null, 1);
}
3.整体代码
package com.hopu.demo;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import androidx.annotation.Nullable;
public class DBHelper extends SQLiteOpenHelper {
public DBHelper(@Nullable Context context) {
super(context, "info.db", null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
4.创建表
为了减少学习成本,DBHelper#getWritableDatabase很贴心的为大家提供了最纯粹的sql执行方式。execSQL使用这个方法就是直接对着建好的库进行一系列数据库操作了。我们就来用这个方法建表。建表语句建议写在onCreate里。另外考虑到重复建表的问题,考虑加上if not exists。
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table if not exists user_table (user_id integer primary key, user_name text, update_time integer)");
}
5.SQLite的数据类型
2.3使用SQLite数据库对数据进行增删改查
2.3.1插入功能
除了使用execSQL
来直接运行sql命令外,还可以使用Android封装的insert
方法来进行数据插入
execSQL方法
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.execSQL("insert into user_table(user_id, user_name, update_time) values(?,?,?)", new String[]{String.valueOf(3),'李四','2'});
insert()方法
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("user_id", 1);
values.put("user_name", "张三");
db.insert("user_table", null, values);
2.3.2删除
使用Android封装的delete
方法来进行数据删除。第一个入参是表名,第二个是删除条件,用?
来占位,第三入参是第二个参数的数据填充。
execSQL方法
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.execSQL("delete from user_table where user_id = ?", new String[]{String.valueOf(3)});
delete()方法
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.delete("user_table", "user_id=?", new String[]{String.valueOf(userId)});
2.3.3更新
使用Android封装的update
方法来进行数据更新。第一个入参是表名,第二个是更新键值对,第三四个入参与删除的2、3入参一样就是更新条件。
execSQL方法
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.execSQL("update user_table set user_name = ? where user_id = ?", new String[]{"赵六",String.valueOf(3)});
update()方法
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("user_name", "王五");
values.put("update_time", 3);
db.update("user_table", values, "user_id=?", new String[]{String.valueOf(3)});
2.3.4查询
使用Android封装的query
方法来进行数据查询。第一个入参是表名,第二个是查询列明,第三四个入参与删除的2、3入参一样就是查询条件,第五、第六、第七分别为聚和条件、虚表条件(写后台时也没用过)以及排序条件。
execSQL方法
SQLiteDatabase db = dbHelper.getWritableDatabase();
List<User> list = new ArrayList<>();
Cursor cursor = db.rawQuery("select * from user_table");
while (cursor.moveToNext()) {
int userId = cursor.getInt(cursor.getColumnIndex("user_id"));
String userName = cursor.getString(cursor.getColumnIndex("user_name"));
long updateTime = cursor.getLong(cursor.getColumnIndex("update_time"));
User res = new User(userId, userName, updateTime);
list.add(res);
}
cursor.close();
return list;
query()方法
SQLiteDatabase db = dbHelper.getWritableDatabase();
List<User> list = new ArrayList<>();
Cursor cursor = db.query("user_table", null, null, null, null, null, null);
if (cursor.moveToFirst()) {
do {
int userId = cursor.getInt(cursor.getColumnIndex("user_id"));
String userName = cursor.getString(cursor.getColumnIndex("user_name"));
long updateTime = cursor.getLong(cursor.getColumnIndex("update_time"));
User res = new User(userId, userName, updateTime);
list.add(res);
} while (cursor.moveToNext());
}
cursor.close();
return list;