@1 SharedPreferences和SharedPreferences.Editor解读
SharedPreferences用于存储类似配置信息的内容,主要是简单的键值对(key-value)。
对于数据存储,无非是 读和写。关于SharedPreferences存储数据:
SharedPreferences本身用于读取(getXXX(key,defvalue))数据。没有关于写数据的方法。SharedPreferences通过edit()方法获取Editor对象用于写入数据(putXXX(key,value))。
SharedPreferences是接口,无法直接创建,需通过Context的getSharedPreferences()方法获取。
@2 SharedPreferences使用解读
//定义SharedPreferences sharedPreferences;SharedPreferences.Editor edit;//获取SharedPreferences,参数Context.MODE_PRIVATE表示该数据只能被本程序读写sharedPreferences = getSharedPreferences("ags", Context.MODE_PRIVATE);//写入数据edit = sharedPreferences.edit();edit.putFloat("floatValue",3.14f);edit.putBoolean("BooleanValue",true);edit.putString("StringValue","AGSTestStringValue");edit.apply();//提交数据//读取数据float floatValue = sharedPreferences.getFloat("floatValue",0.0f);Boolean boolValue = sharedPreferences.getBoolean("BooleanValue",false);String stringValue = sharedPreferences.getString("StringValue","");
关于数据提交的说明:
apply() 不会阻塞前台线程,后台提交修改。commit方法会阻塞前台线程但会立即生效。
@3 SharedPreferences存储路径
SharedPreferences数据存储在/data/data/<应用包名>/shared_prefs目录下,以xml格式保存,内容为键值对(key-value)。
@4 SharedPreferences官方文档
SharedPreferences更详细解读参照文档:Android SharedPreferences类详解SharedPreferences.Editor更详细解读参照文档:Android SharedPreferences.Editor类详解2 IO流 文件存储 2.1 APP内部文件存储
@1 文件存储基础
关于Android的文件存储,我们关注 打开/关闭、读/写,实际上和java原生的IO体系类似,尤其是读写,都是read/write。因此这里简述文件和文件夹的打开/关闭(主要针对APP内文件存储)。
@2 使用解读
关于文件,Context本身提供2个关键API(openFileOutput和openFileInput),使用如下所示:
//1 定义输入流FileInputStream fileInputStream = null;//打开操作,注意try catchtry { //打开应用程序 数据文件夹下的test文件 输入流 fileInputStream = openFileInput("test");} catch (FileNotFoundException e) { e.printStackTrace();}//关闭操作,注意try catchif(fileInputStream!=null) { try { fileInputStream.close(); } catch (IOException e) { e.printStackTrace(); }}//2 定义输出流FileOutputStream fileOutputStream = null;//打开操作,注意try catchtry { //打开应用程序 数据文件夹下的test文件 输出流 //参数MODE_PRIVATE表示只能被当前程序读写,如果改为MODE_APPEND则表示追加内容 fileOutputStream = openFileOutput("test",MODE_PRIVATE);} catch (FileNotFoundException e) { e.printStackTrace();}//关闭操作,注意try catchif(fileOutputStream!=null){ try { fileOutputStream.close(); } catch (IOException e) { e.printStackTrace(); }}
关于文件夹,Context本身提供的关键API。使用如下所示:
//常见文件夹操作File fileDir = getDir("dirtest",MODE_PRIVATE); //获取文件夹dirtest句柄File fileDir2 = getFilesDir(); //获取应用程序 数据文件夹的绝对路径String[] dir = fileList();//列出应用程序 数据文件夹下的 全部文件deleteFile("filetest");//删除应用程序 数据文件夹下的 指定文件 filetest//常见文件夹路径整理getCacheDir().getAbsolutePath(); //路径 /data/user/0/<应用包名>/cache getFilesDir().getAbsolutePath(); //路径 /data/user/0/<应用包名>/filesgetExternalCacheDir().getAbsolutePath(); //路径 /storage/emulated/0/Android/data/<应用包名>/cachegetExternalFilesDir(null).getAbsolutePath(); //路径 /storage/emulated/0/Android/data/<应用包名>/files
@3 文件操作的权限
在SD卡上存储文件均需在AndroidManifest.xml文件中添加权限:
@4 存储路径
数据存储在/data/data/<应用包名>/files 文件夹下。
@5 Context中 数据文件/文件夹 官方文档
注意:虽然很多文件操作 我们是通过Context来获取文件的相关API,但这些API实际上是定义在ContextWrapper类中的,详细解读如下:Android ContextWrapper类详解
2.2 APP外 文件存储以上所涉及的是针对应用程序内数据文件/文件夹的相关操作。如果需要访问SD卡,则需要:
//获取SD卡目录的路径String sdcardDir = Environment.getExternalStorageDirectory();
关于权限,如果需要创建/删除文件,那么还需要 挂载/卸载 权限(注意:系统APP),如下所示:
注意:在Android Q中该方法已被弃用,在Android Q之后不推荐使用该方法,如果要使用,需在权限之外 在 application节点中添加。
android:requestLegacyExternalStorage="true"
如果不使用该方法也可以,参照(引自 Android解决getExternalStorageDirectory在29后废弃问题)代码:
//通过APP所在路径 层层回滚到上级目录,直到Android,然后再拼接File externalFileRootDir = getExternalFilesDir(null);do { externalFileRootDir = Objects.requireNonNull(externalFileRootDir).getParentFile();} while (Objects.requireNonNull(externalFileRootDir).getAbsolutePath().contains("/Android"));String saveDir = Objects.requireNonNull(externalFileRootDir).getAbsolutePath();String savePath = saveDir + "/" + Environment.DIRECTORY_DCIM + "/" + filename;
3 数据库Sqlite简介(关键接口说明)Android集成了轻量级Sqlite数据库,本质上是一种更加便捷的文件操作。关于这部分,首先回顾下数据库的基础知识:SQLite 简介 | 菜鸟教程。有了这个基础,加上本质上Android是对数据库Sqlite集成,因此该部分内容更依赖于对数据库的理解,该部分主要是对封装的关键类进行解读。
3.1 SQLiteDatabase类解读SQLiteDatabase类既代表与数据库的连接,又可用于执行sql语句。相关操作整理如下:
//1 打开/创建数据库,从文件 或者 路径中读取数据库static SQLiteDatabase openOrCreateDatabase (File file,SQLiteDatabase.CursorFactory factory)static SQLiteDatabase openDatabase(String path, SQLiteDatabase.CursorFactory factory, int flags, DatabaseErrorHandler errorHandler);static SQLiteDatabase openDatabase(String path, SQLiteDatabase.CursorFactory factory, int flags);static SQLiteDatabase openOrCreateDatabase(String path, SQLiteDatabase.CursorFactory factory, DatabaseErrorHandler errorHandler);static SQLiteDatabase openOrCreateDatabase(String path, SQLiteDatabase.CursorFactory factory);//2 执行SQL语句execSQL(String sql , Object[] args); //执行带占位符的sql语句//Android考虑到有不熟悉sql语句的开发者,提供了进一步封装后的一系列方法,即:long insert(String table,String nullColumnHack,ContentValues values);//插入记录int delete(String table,String whereClause,String[] whereArgs);//删除一条记录Cursor query(String table,String[] columns,String selection,String[] selectionArgs,String groupBy,String having,String orderBy);//查询一条记录Cursor rawQuery (String sql,String[] selectionArgs,CancellationSignal cancellationSignal);//查询一条记录,sql语句模式int update(String table,ContentValues values,String whereClause,String[] whereArgs);//修改记录//事物开始/结束beginTransaction();//开始事务endTransaction(); //结束事务inTransaction(); //处于事务上下文中,处于返回true,不处于返回false。
注意:rawQuery直接使用SQL语句进行查询,在第一个参数字符串内的“?”会被后面的String[]数组逐一对换掉;而query函数是Android自己封装的查询API,在实际使用场景中,query方法更不容易出错。
关于,更多详细内容查看官方文档:Android SQLiteDatabase类详解
3.2 SQLiteOpenHelper类解读在真实的项目中更多的是使用工具类SQLiteOpenHelper来创建数据库 而不是使用SQLiteDatabase的openXXX方法来获取数据库的句柄(SQLiteOpenHelper是SQLiteDatabse的一个帮助类,用来管理数据的创建和版本更新,可以理解为对SQLiteDatabase的一种封装)。这里主要介绍SQLiteOpenHelper 打开数据库的方法。先定义一个子类,代码如下所示:
public class DbOpenHelper extends SQLiteOpenHelper { public DbOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { super(context, name, null, 1); } @Override //第1次创建时调用 public void onCreate(SQLiteDatabase db) { } @Override //数据库升级时自动调用 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { }}
之后 使用该对象,如下所示:
//1 打开数据库DbOpenHelper dbOpenHelper = new DbOpenHelper(MainActivity.this,"testDB",null,1);//创建/打开 可读数据库SQLiteDatabase sqLiteDatabaseR = dbOpenHelper.getReadableDatabase();//创建/打开 可读写数据库SQLiteDatabase sqLiteDatabaseRW = dbOpenHelper.getWritableDatabase();//2 关于数据库操作:使用SQLiteDatabase的操作SQl的方式 或 封装的增删改查方法均可。//3 关闭数据库,一次性关闭dbOpenHelper中所有的SQLiteDatabase类型句柄。dbOpenHelper.close();
关于,更多详细内容查看官方文档:Android SQLiteOpenHelper类详解
3.3 Android的 sqlite3 命令执行adb shell,进入到终端,然后执行:
$cd data/data/
列出数据库文件,接下来进入数据库,比如:
$sqlite3 test_db
显示如下内容:接下来可以对数据库进行命令行操作
SQLite version 3.6.22Enter ".help" for instructionsEnter SQL statements terminated with a ";"sqlite>
常见sqlite3使用语句如下:
>.databases ----产看当前数据库>.tables ----查看当前数据库中的表>.help ----帮助信息,所有命令的解读