栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Android APP完整基础教程(18)存储

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android APP完整基础教程(18)存储

1 SharedPreferences和Editor

@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 catch
try {
    //打开应用程序 数据文件夹下的test文件 输入流
    fileInputStream = openFileInput("test");
} catch (FileNotFoundException e) {
    e.printStackTrace();
}
//关闭操作,注意try catch
if(fileInputStream!=null) {
    try {
        fileInputStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

//2 定义输出流
FileOutputStream fileOutputStream = null;
//打开操作,注意try catch
try {
    //打开应用程序 数据文件夹下的test文件 输出流
    //参数MODE_PRIVATE表示只能被当前程序读写,如果改为MODE_APPEND则表示追加内容
    fileOutputStream = openFileOutput("test",MODE_PRIVATE);
} catch (FileNotFoundException e) {
    e.printStackTrace();
}
//关闭操作,注意try catch
if(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/<应用包名>/files
getExternalCacheDir().getAbsolutePath(); //路径 /storage/emulated/0/Android/data/<应用包名>/cache
getExternalFilesDir(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//databases
$ls   

列出数据库文件,接下来进入数据库,比如:

$sqlite3 test_db

显示如下内容:接下来可以对数据库进行命令行操作

SQLite version 3.6.22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite>

常见sqlite3使用语句如下:

>.databases ----产看当前数据库
>.tables    ----查看当前数据库中的表
>.help      ----帮助信息,所有命令的解读

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/731512.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号