《第一行代码》 第六章:数据库与存储方案

news2024/12/24 8:57:11

一,持久化技术简介

也就是数据存储在内存中,会丢失。需要存储在存储设备中。而持久化技术,就是提供了手段,让数据再试瞬时状态和持久状态之间转换。
安卓开发提供了三种数据的持久化技术:
在这里插入图片描述

二,文件存储

文件存储不对存储内容进行任何的格式化处理,所有数据都是原封不动地保存到文件当中,因而它比较适合用于存储一些简单地文本数据。

Context 类中提供了一个openFileOutput()方法,可以用于将数据存储到指定的文件中。
这个方法接收两个参数,

第一个参数是文件名,在文件创建的时候使用的就是这个名称,注意这里指定的文件名不可以包含路径,因为所有的文件都是默认存储到/data/data/<packagename/files/目录下的。
第二个参数是文件的操作模式,主要有两种模式可选,MODE PRIVATE和MODE APPEND。其中MODE PRIVATE是默认的操作模式,表示当指定同样文件名的时候所写入的内容将会覆盖原文件中的内容,而MODE APPEND 则表示如果该文件已存在,就往文件里面追加内容,不存在就创建新文件。

下面的代码展示了如何将一段文本内容存储道文件中:

    public void save(String inputText) {
        FileOutputStream out=null;
        BufferedWriter writer=null;
        try {
            out=openFileOutput("data", Context.MODE_PRIVATE);
            writer=new BufferedWriter(new OutputStreamWriter(out));
            writer.write(inputText);
        }catch(IOException e){
            e.printStackTrace();
        }finally {
            try {
                if(writer!=null){
                    writer.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }

主要就是这三行代码:

           out=openFileOutput("data", Context.MODE_PRIVATE);
            writer=new BufferedWriter(new OutputStreamWriter(out));
            writer.write(inputText);

构建出writer对象,就可以writer.write(inputText);写入文件。

1,新建FilePersistenceTest项目

修改其中的activity_main.xml文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <EditText
        android:id="@+id/edit"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#00ff00"
       android:hint="请输入内容"/>

</LinearLayout>

2,修改MainActivity文件

public class MainActivity extends AppCompatActivity {
    private EditText edit;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        edit=(EditText) findViewById(R.id.edit);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        String inputText =edit.getText().toString();
        save(inputText);
    }

    public void save(String inputText) {
        FileOutputStream out=null;
        BufferedWriter writer=null;
        try {
            //文件名字是:data,文件书写类型是覆盖
            out=openFileOutput("data", Context.MODE_PRIVATE);
            //将文件写入的参数传入,构建出writer对象
            writer=new BufferedWriter(new OutputStreamWriter(out));
            //调用writerd的write方法,写入文件。
            writer.write(inputText);
        }catch(IOException e){
            e.printStackTrace();
        }finally {
            try {
                if(writer!=null){
                    writer.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }
}

在该活动被销毁的时候,就会调用save方法,把文本写入文件中。

3,查看文件内容

书中的查看方法已经被弃用了,新的查看方法是:在Android Studio的顶部栏,View >> Tool Windows >> Device File Explorer;然后再在文件夹data/data中查看即可。
在这里插入图片描述
这样就可以在文件中看到。

4,从文件中读取数据

类似于将数据存储到文件中,Context 类中还提供了一个 openFileInput()方法,用于从文件中读取数据。这个方法要比 openFileOutput()简单一些,它只接收一个参数,即要读取的文件名,然后系统会自动到/data/data//files/目录下去加载这个文件,并返回一个FileInputstream 对象,得到了这个对象之后再通过Java流的方式就可以将数据读取出来了。
示例如下:

    public String load(){
        FileInputStream  in=null;
        BufferedReader reader=null;
        StringBuilder content=new StringBuilder();
        try {
            //配置读取参数
            in = openFileInput("data");
            //使用读取参数构建reader
            reader=new BufferedReader(new InputStreamReader(in));
            String line="";
            //一行行读取内容,并且放置到content中
            while((line=reader.readLine())!=null){
                content.append(line);
            }
        }catch(IOException e){
            e.printStackTrace();
        }finally {
            try {
                if(reader!=null){
                    reader.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
        return content.toString();
    }

于是仅需要修改上文的MainActivity中的代码即可:

public class MainActivity extends AppCompatActivity {
    private EditText edit;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        edit=(EditText) findViewById(R.id.edit);
        String inputText=load();
        if(!TextUtils.isEmpty(inputText)){
            //读取到内容了就更新
            edit.setText(inputText);
            //焦点放置到最后位置
            edit.setSelection(inputText.length());
            Toast.makeText(this, "读取到内容啦", Toast.LENGTH_SHORT).show();
        }

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        String inputText =edit.getText().toString();
        save(inputText);
    }

    public void save(String inputText) {
        FileOutputStream out=null;
        BufferedWriter writer=null;
        try {
            //文件夹名字是:data,文件书写类型是覆盖
            out=openFileOutput("data", Context.MODE_PRIVATE);
            //将文件写入的参数传入,构建出writer对象
            writer=new BufferedWriter(new OutputStreamWriter(out));
            //调用writerd的write方法,写入文件。
            writer.write(inputText);
        }catch(IOException e){
            e.printStackTrace();
        }finally {
            try {
                if(writer!=null){
                    writer.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }

    public String load(){
        FileInputStream  in=null;
        BufferedReader reader=null;
        StringBuilder content=new StringBuilder();
        try {
            //配置读取参数
            in = openFileInput("data");
            //使用读取参数构建reader
            reader=new BufferedReader(new InputStreamReader(in));
            String line="";
            //一行行读取内容,并且放置到content中
            while((line=reader.readLine())!=null){
                content.append(line);
            }
        }catch(IOException e){
            e.printStackTrace();
        }finally {
            try {
                if(reader!=null){
                    reader.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
        return content.toString();
    }
}

实现的效果:
在这里插入图片描述

三,SharedPreferences存储

这种存储方案有以下几个特点:

1,以键值对进行存储
2,支持多种数据结构进行存储,存的时候是什么数据结构,取出来的时候就是什么数据结构。

将数据存储到SharedPreferences的第一步是需要获取SharedPreferences对象。有以下三种方法:

1,Context类中的getSharedPreferences()方法

此方法接收两个参数,第一个参数用于指定 SharedPreferences 文件的名称,如果指定的文件不存在则会创建一个,SharedPreferences 文件都是存放在/data/data//shared prefs/目录下的。
第二个参数用于指定操作模式,目前只有 MODE PRIVATE这一种模式可选,它是默认的操作模式,和直接传入 0 效果是相同的,表示只有当前的应用程序才可以对这个SharedPreferences 文件进行读写。

2,Activity类中的getPreferences

这个方法和Context中的 getSharedPreferences()方法很相似,不过它只接收一个操作模式参数,因为使用这个方法时会自动将当前活动的类名作为SharedPreferences 的文件名。

3,PreferenceManager类中的 getDefaultSharedPreferences()方法

这是一个静态方法,它接收一个 Context 参数,并自动使用当前应用程序的包名作为前缀来命名 SharedPreferences 文件。

4,向SharedPreferences文件中存储数据

(1)调用SharedPreferences 对象的edit)方法来获取一个SharedPreferences.Editor对象。
(2)向 sharedPreferences.Editor 对象中添加数据,比如添加一个布尔型数据就使用putBoolean()方法,添加一个字符串则使用 putstring()方法,以此类推。
(3)调用 apply()方法将添加的数据提交,从而完成数据存储操作。

5,第一步:新建项目,修改Main_activity.html

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        android:id="@+id/save_data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="保存"/>

</LinearLayout>

6,第二步,修改activity文件

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button saveData =(Button) findViewById(R.id.save_data);
        saveData.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view) {
                SharedPreferences.Editor editor=getSharedPreferences("data",MODE_PRIVATE).edit();
                editor.putString("name","Tom");
                editor.putInt("age",24);
                editor.putBoolean("married",false);
                editor.apply();
            }
        });
    }
}

点击按钮后,立马就保存了,需要在Android Studio的顶部栏,View >> Tool Windows >> Device File Explorer;然后再在文件夹data/data中查看即可。
在这里插入图片描述

7,从SharedPreferences中读取数据

修改xml中代码:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        android:id="@+id/save_data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="保存"/>
    <Button
        android:id="@+id/restore_data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="获取数据"/>

</LinearLayout>

修改活动中的代码:

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button saveData =(Button) findViewById(R.id.save_data);
        Button restoreData =(Button) findViewById(R.id.restore_data);
        saveData.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view) {
                SharedPreferences.Editor editor=getSharedPreferences("data",MODE_PRIVATE).edit();
                editor.putString("name","Tom");
                editor.putInt("age",24);
                editor.putBoolean("married",false);
                editor.apply();
            }
        });
        restoreData.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view) {
                SharedPreferences pref=getSharedPreferences("data",MODE_PRIVATE);
                String name=pref.getString("name","");
                Toast.makeText(MainActivity.this, name, Toast.LENGTH_SHORT).show();
            }
        });
    }
}

四,SQLite数据库

android有提供数据库。现在已经有开源的库LitePal来实现数据的增删改查。
它采用了对象关系映射(ORM)的模式,这是让我们非常好的理解的数据库,一个实体类对应我们数据库中的一个表。该库中还封装了许多的方法,就算对SQL语句的了解很少,也能很好的建立起数据库,以及各种增删改查的操作。
这一节,因为照着书上的方式,会报错。跳过先

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/360212.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【HDFS】FsDatasetImpl#getReplicaVisibleLength

调用点 DataNode.getReplicaVisibleLength(ExtendedBlock) (org.apache.hadoop.hdfs.server.datanode) // ClientDataNodeProtocolBlockChecksumComputer in BlockChecksumHelper.BlockChecksumComputer(DataNode, ExtendedBlock, BlockChecksumOptions) (org.apache.hadoop.hd…

ros中时间的概念:ros::Time、ros::Duration、定时器ros::Timerros::Rate、ros::WallTime

1. ros时间格式说明 有时刻和持续时长(可以是负数)&#xff0c;分为秒和纳秒&#xff0c;换算关系&#xff1a;1sec1e9nsec。Time指的是某个时刻&#xff0c;而Duration指的是某个时段。 int32 sec int32 nsec 2. ros::Time::now() 记录当前时刻 3. ros::Duration 代表持续的…

Linux 输出重定向 “>”、“>>”、“freopen”

有时候&#xff0c;我们编码时会使用printf或fprintf去打印输出调试信息或者报错信息&#xff0c;但正常这样去打印&#xff0c;只会显示在终端&#xff0c;如果终端关闭了&#xff0c;或者系统宕机了等&#xff0c;这些输出信息就没有了&#xff0c;为了将这些重要的信息保存下…

java诊断与调优常用命令jmap、jstack、jstat使用实战

java应用运行过程中难免会出现问题&#xff0c;特别是在生产环境&#xff0c;发生异常或宕机情况&#xff0c;需要诊断与分析&#xff0c;定位原因&#xff0c;进行优化&#xff0c;避免下次再次出现问题。 虽然现在有很多可视化工具&#xff0c;使用起来比命令行更方便&#x…

开学季好用电容笔有哪些?好用实惠的电容笔推荐

随着科学技术的快速发展&#xff0c;ipad的影响力越来越大&#xff0c;而且ipad的用户也越来越多&#xff0c;如果要提高ipad的功能&#xff0c;让ipad更加有趣&#xff0c;那么就需要一款非常适合自己&#xff0c;并且非常实用的电容笔。那么&#xff0c;究竟该选择哪个品牌的…

SpringBoot整合分布式锁redisson

1、导入maven坐标<!-- 用redisson作为所有分布式锁&#xff0c;分布式对象等功能框架--><dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.12.5</version></dependency>2、red…

蓝牙 - BLE中的连接和扫描参数设定

连接参数 / Connection Parameters 连接参数由发起设备与连接请求一起发送&#xff0c;当连接建立后&#xff0c;任何一个设备都可以修改。这些参数如下&#xff1a; 连接间隔 / Connection Interval 在低功耗蓝牙连接中&#xff0c;使用了跳频方案。两台设备发送各自数据和接…

day48【代码随想录】动态规划之最长递增子序列、最长连续递增序列、最长重复子数组

文章目录前言一、最长递增子序列&#xff08;力扣300&#xff09;二、最长连续递增序列&#xff08;力扣674&#xff09;三、最长重复子数组&#xff08;力扣718&#xff09;前言 1、最长递增子序列 2、最长连续递增序列 3、最长重复子数组 一、最长递增子序列&#xff08;力扣…

rocketmq延时消息自定义配置;topic下tag使用

概述 使用的是开源版本的rocketmq4.9.4 rocketmq也是支持延时消息的。 rocketmq一般是4个部分&#xff1a; nameserver&#xff1a;保存路由信息broker&#xff1a;保存消息生产者&#xff1a;生产消息消费者&#xff1a;消费消息 延时消息的处理是在其中的broker中。 但是…

我为什么放弃WinUI3

基于WinUI3开发HiNote已经有一个多月的时间了&#xff0c;算是做出来一个简单能用的C端软件。 基于个人的经历&#xff0c;说说其中的开发体验。 UI设计语言 无论是否抄袭苹果&#xff0c;WinUI3给人的感觉都是眼前一亮的。简洁美观&#xff0c;现代化&#xff0c;毛玻璃的美…

rk3568网口CAN串口通信速率性能

通信接口性能参数外设接口性能参数测试结果为实验室实测值&#xff0c;可作为设计参考&#xff0c;但因测试环境和器件批次差异&#xff0c;可能会存在一定的误差&#xff0c;且测试结果依赖评估板性能&#xff0c;核心板搭配不同底板性能也可能存在差异&#xff0c;请结合实际…

Redis之分布式锁

随着业务发展的需要&#xff0c;原单体单机部署的系统被演化成分布式集群系统后&#xff0c;由于分布式系统多线程、多进程并且分布在不同机器上&#xff0c;这将使原单机部署情况下的并发控制锁策略失效&#xff0c;单纯的 Java API并不能提供分布式锁的能力。为了解决这个问题…

Java:顶级Java应用程序服务器 — Tomcat、Jetty、GlassFish、WildFly

如果你想编写Java web应用程序&#xff0c;首先需要做出一个艰难的决定&#xff1a;选择运行应用程序的Java应用程序服务器。什么是应用服务器?一般来说&#xff0c;应用程序服务器执行Java应用程序。在操作系统中启动它们&#xff0c;然后将应用程序部署到其中。将应用程序服…

盘点2023年大企业都在用的优秀项目管理软件

行内有句话&#xff1a;每个成功的项目背后肯定有一个成功的项目经理&#xff0c;而每个项目经理背后都少不了一些专业的项目管理工具。要在任何项目中取得成功&#xff0c;对项目进行全面的管理非常关键&#xff0c;包括项目的执行、计划、推进、监控、结果等&#xff0c;有了…

谈谈我对ai发展的看法

最近难得有时间&#xff0c;通过白话&#xff0c;聊聊我对AI的看法&#xff0c;仅代表个人观点首先表明我的观点&#xff1a;人类当前的人工智能成果&#xff0c;仍然停留在一知半解程度。技术的发展是需要长期的积累和进步&#xff0c;目前AI的发展仍处于入门阶段人类的发展必…

ar远程协助可视化云平台提高患者的医疗体验

“专家的指导意见很科学&#xff0c;患者恢复很快&#xff0c;情况稳定就可以转入普通病房了!这种云急救对基层医院来说太及时太必要了!大专家不用奔波&#xff0c;我们又提高了救治能力和效率!”这是来自某市基层主任的心里话。 传统远程协助的局限性 传统远程带来了便捷的线上…

【Java基础】输入与输出

输入与输出 输入 获取用键盘输入常用的两种方法 方法 1&#xff1a;通过 Scanner Scanner input new Scanner(System.in); String s input.nextLine(); input.close();方法 2&#xff1a;通过 BufferedReader BufferedReader input new BufferedReader(new InputStrea…

实验室设计|实验室设计要点SICOLAB

一、实验室设计规划要素1、实验室布局&#xff1a;实验室的布局要符合实验室工作流程&#xff0c;可以将实验室划分为干净区和污染区&#xff0c;以确保实验室的卫生和实验的准确性。2、设备选购&#xff1a;根据实验需要选择适当的设备&#xff0c;并确保设备的质量和性能符合…

LA@ML特征分解@奇异值分解@伪逆

文章目录特征分解几何示意图二次型和生成子空间奇异值分解理论数学风格的描述奇异值分解和特征分解的联系&#x1f60a;&#x1f388;机器学习风格的描述对角矩阵的记法酉矩阵unitary matrix性质Moore-Penrose 伪逆矩阵的逆和线性方程组的解(review)伪逆应用迹运算方阵行列式和…

代谢组+转录组分析为腰果树果实发育成熟过程中代谢网络提供见解

文章标题&#xff1a;Metabolomic and transcriptomic analyses provide insights into metabolic networks during cashew fruit development and ripening 发表期刊&#xff1a;Food Chemistry 影响因子&#xff1a;9.231 作者单位&#xff1a;海南大学 百趣生物提供服务…