Android的存储
-
无论是桌面应用程序还是Android手机应用程序,都会涉及数据的存储。
-
在 Android 中应用程序存储的数据(包括文件)都属于应用程序私有,但同时也提供了 ContentProviders(数据共享),方便应用程序将私有的数据分享给其他程序使用。
-
数据存储方式共分为5种,分别为:
-
SharedPreferences。
-
内部存储(Internal Storage)。
-
外部存储(External Storage)。
-
SQLite数据库存储。
-
网络存储。(现阶段主流)
-
我们现在主要学习两种
-
1.SharedPreferences
-
2.什么是SQLite
1.
调用 SharedPreferences.Editor 的 commit() 方法将更新提交到 SharedPreferences 中
代码实现:
activity_main.xml
<?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
-
SharedPreferences
-
3.1 SharedPreferences简介
-
SharedPreferences 是 Android 系统提供的一个通用的数据持久化框架,用于存储和读取 key-value 类型的原始基本数据对。
-
目前仅支持 boolean、float、int、long 和 string 等基本类型的存储,对于自定义的复合数据类型,是无法使用 SharedPreferences 进行存储的。
-
SharedPreferences 主要用于存储系统的配置信息,类似于 Windows 下常用的 .ini 文件。
-
例如上次登录的用户名、上次最后设置的信息等,通过保存上一次用户所做的修改或者自定义参数设定,当再次启动程序后依然保持原有设置。它是用键值对的方式存储的,方便管理写入和读取。
-
使用 SharedPreferences 的步骤如下:
-
获取Preferences
每个 Activity 默认都有一个 SharedPreferences 对象,获取 SharedPreferences 对象的方法有两种:
1)SharedPreferences getSharedPreferences(String name, int mode)。
使用该方法获取 name 指定的 SharedPreferences 对象,并获取对该 SharedPreferences 对象的读写控制权。
当应用程序中可能使用到多个 SharedPreferences 时使用该方法。
2)SharedPreferences getPreferences(int mode)。
当应用程序中仅需要一个SharedPreferences对象时,使用该方法获取当前 Activity 对应的 SharedPreferences,而不需要指定 SharedPreferences 的名字。
其中,参数 mode 有 4 种取值,分别是:
-
MODE_PRIVATE:默认方式,只能被创建的应用程序或者与创建的应用程序具有相同用户 ID 的应用程序访问。
-
MODE_WORLD_READABLE:允许其他应用程序对该 SharedPreferences 文件进行读操作。
-
MODE_WORLD_WRITEABLE:允许其他应用程序对该 SharedPreferences 文件进行写操作。
-
MODE_MULTI_PROCESS:在多进程应用程序中,当多个进程都对同一个 SharedPreferences 进行访问时,该文件的每次修改都会被重新核对。
-
-
获取 SharedPreferences.Editor
调用 edit() 方法获取 SharedPreferences.Editor,SharedPreferences 通过该接口对其内容进行更新。
-
更新 SharedPreferences
通过 SharedPreferences.Editor 接口提供的 put 方法对 SharedPreferences 进行更新。
例如使用 putBoolean(String key, boolean value)、putFloat(String key, float value) 等方法将相应数据类型的数据与其 key 对应起来。
-
提交
-
-
. 当用户在该实例运行时,在文本框中输入电话号码和所在城市,例如 13800000000 和 beijing,单击回退按钮退出应用程序时,该应用程序将相关信息写入其对应的 SharedPreferences 中。
-
当用户再次启动该应用程序时,之前填写到文本框内的信息会被从 SharedPreferences 中读取并显示出来,以方便用户修改。
1 SQLite简介
SQLite是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。它是一个零配置的数据库,这意味着与其他数据库不一样,您不需要在系统中配置。就像其他数据库,SQLite 引擎不是一个独立的进程,可以按应用程序需求进行静态或动态连接。SQLite 直接访问其存储文件。
2 为什么要使用SQLite
不需要一个单独的服务器进程或操作的系统(无服务器的)。
SQLite 不需要配置,这意味着不需要安装或管理。
综合来看,即轻量 兼容 多端 无需配置 无外部依赖 拥有简单易懂的API 安全
-
一个完整的 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)中运行。
1 常见数据库步骤
创建DBHelper.java
让创建的DBHelper继承SQLiteOpenHelper
继承的抽象类SQLiteOpenHelper中的两个抽象方法
创建带全部参数的DBHelper类的构造函数以便于生成数据库对象
类型 | SQLITE | JAVA |
---|---|---|
整型 | INTEGER | byte, short, int, long |
浮点型 | REAL | float, double |
字符串 | TEXT | String |
布尔串 | BLOB | boolean |
4.4.3 主键自增
autoincrement
4.3.2 生成数据库
我们给数据库起名为“info.db”,数据库版本号为1,需要对构造方法进行修改。代码如下:
public DBHelper(@Nullable Context context) { super(context, "info.db", null, 1); }
4.3.3 DBHelper的整体代码
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.4 创建表
4.4.1 创建表的过程
为了减少学习成本,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)"); }
4.4.2 SQLite的数据类型很简单
使用SQL语句操作数据库
-
当然,你可能已经学过SQL,会写相关的SQL语句,而且不想用Android提供的这些API,
你可以直接使用SQLiteDatabase给我们提供的相关方法:execSQL(SQL,Object[]):使用带占位符的SQL语句,这个是执行修改数据库内容的sql语句用的
rawQuery(SQL,Object[]):使用带占位符的SQL查询操作
另外前面忘了介绍下Curosr这个东西以及相关属性,这里补充下:
——Cursor对象有点类似于JDBC中的ResultSet,结果集!使用差不多,提供一下方法移动查询结果的记录指针:
move(offset):指定向上或者向下移动的行数,整数表示向下移动;负数表示向上移动!
moveToFirst():指针移动到第一行,成功返回true,也说明有数据
moveToLast():指针移动到最后一样,成功返回true;
moveToNext():指针移动到下一行,成功返回true,表明还有元素!
moveToPrevious():移动到上一条记录
getCount( )获得总得数据条数
isFirst():是否为第一条记录
isLast():是否为最后一项
moveToPosition(int):移动到指定行
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);
4.5.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)});
4.5.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)});
4.5.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;