Android入门(8)| 数据存储

作者: yzbkaka | 来源:发表于2019-01-22 16:03 被阅读6次
    本节目录

    文件存储

    文件存储是一种最为基本的存储方式,它的特点是不会对存储内容做出任何的修改或者格式化的操作,直接就是将数据内容按照它自己的方式来保存到文件当中。

    1.存储数据

    用文件存储的方式来对数据进行存储主要使用的方法就是openFileOutput()。下面我们就一起来看一看吧。首先还是先创建一个空项目,并且为该项目的主布局添加一个EditText用于输入数据,然后修改主代码:

    package com.example.yzbkaka.filepersistencetest;
    
    import android.content.Context;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.widget.EditText;
    
    import java.io.BufferedWriter;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStreamWriter;
    
    public class MainActivity extends AppCompatActivity {
        EditText editText;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            editText = (EditText)findViewById(R.id.text_view);  //获得EditText实例
        }
    
        protected void onDestroy(){
            super.onDestroy();
            String inputText = editText.getText().toString();  //得到输入的内容
            save(inputText);  //存储输入的内容
        }
    
        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();
                }
            }
        }
    }
    

    分析代码,我们先是在onDestroy()的方法中获得在EditText中输入的数据,接着就是调用我们自己写的save()方法来将数据进行存储了。在save()方法中,我们主要是采用Java流的方式来对数据进行存储,即首先是创建FileOutputStream的实例并且使用openFileOutput()方法来获得实例,openFileOutput()的方法中需要两个参数:第一个参数是我们要将数据存储的文件夹的名称(如果不存在该文件夹则会在/data/data/<packgename>/files/创建一个该名字的新文件夹);第二个参数是文件的操作方式,一般有两种方式供我们选择,MODE_PRIVATE(默认)和MODE_APPEND,前者是指当指定同样的文件名时所写入的内容会将原内容给覆盖掉,而后者则是遇到相同文件名时在文件里面追加内容。接着就是将所获得的数据通过OutputStreamWriter传到BufferedWriter的实例当中,最后就是使用BufferedWriter的write()方法来将数据写入。

    我们运行代码,然后输入一行内容,再退出程序就可以将数据存储了。如果想要查看师傅存储成功,我们可以借助Android Device Monitor工具来进行查看。在导航页中找到Tools—>Android,在出现的选择面板中选择Android Device Monitor,然后我们找到/data/data/com.example.filepersistancetest/files/目录中找到data文件,然后点击右上角的导出按钮将其导入到电脑山然后使用记事本打开,就可以看到我们输入的内容了。

    2.读取数据

    将以文件方式存储的数据读取出来主要是使用openFileInput()方法来读取。我们还是使用上面的项目,修改主代码:

    package com.example.yzbkaka.filepersistencetest;
    
    import android.content.Context;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.text.TextUtils;
    import android.widget.EditText;
    import android.widget.Toast;
    
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    
    public class MainActivity extends AppCompatActivity {
        EditText editText;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            editText = (EditText)findViewById(R.id.text_view);
            String inputText = load();  //调用load()方法进行读取
            if(!TextUtils.isEmpty(inputText)){  //判断内容是否为空
                editText.setText(inputText);
                editText.setSelection(inputText.length());  //将光标移动到数据的末尾
                Toast.makeText(this, "restore successfully", Toast.LENGTH_SHORT).show();
            }
        }
    
        protected void onDestroy(){
            super.onDestroy();
            String inputText = editText.getText().toString();
            save(inputText);
        }
    
        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();
                }
            }
        }
    
        public String load(){  //读取内容的方法
            FileInputStream in = null;
            BufferedReader reader = null;
            StringBuilder content = new StringBuilder();
    
            try{
                in = openFileInput("data");
                reader = new BufferedReader(new InputStreamReader(in));
                String line = "";
                while((line = reader.readLine()) != null) {
                    content.append(line);
                }
            } catch(IOException e){
                e.printStackTrace();
            } finally {
                if(reader != null){
                    try{
                        reader.close();
                    }catch(IOException e){
                        e.printStackTrace();
                    }
                }
            }
            return content.toString();
        }
    }
    

    我们是自己写的load()方法来读取内容,读取数据的方式还是按照Java流来进行的,这里面我们使用了openFileInput()的方法,它所需要的参数只有一个,就是我们想要读取内容的文件夹的名称。接着就是按照一行一行的方式来读取数据了。

    运行程序,在输入框里面输入数据,然后退出程序,再次进入程序就会发现输入框里面已经有我们之前输入的内容了。

    SharedPreferences存储

    SharedPreferences是使用键值对的方式来存储数据的。键值对的方式简单来说就是当我们保存一条数据时,需要给这个数据提供几个键值,而当我们读取数据时就可以通过这个键值来将数据提取出来。

    1.存储数据

    使用SharedPreferences存储数据的步骤主要有4步:
    第一步:获取SharedPreferences对象。Android中提供了3种方法来让我们获得SharedPreferences对象,不过我们最常用的就是Context类中的getSharedPreferences()方法来获得对象。
    第二步:调用SharedPreferences中的edit()方法来获取SharedPreferences.Editor对象。
    第三步:向SharedPreferences.Editor对象中添加数据,主要使用的方法就是put...()方法。例如如果我们想要添加一个int类型的数据,我们就可以使用putInt();如果想要添加一个String类型的数据,就可以使用putString()方法。
    第四步:最后就是使用apply()方法来将数据进行提交。

    我们就来实际操作一下。创建一个新项目,为该布局添加一个按钮,然后修改主代码:

    package com.example.yzbkaka.sharedpreferencestest;
    
    import android.content.SharedPreferences;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    
    public class MainActivity extends AppCompatActivity {
        Button save;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            save = (Button)findViewById(R.id.button1);
            save.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    SharedPreferences.Editor editor = getSharedPreferences("data",MODE_PRIVATE).edit();  //获得Editor实例
                    editor.putString("name","yzbkaka");  //导入数据
                    editor.putInt("age",19);
                    editor.putBoolean("married",false);
                    editor.apply();
                }
            });
        }
    }
    

    我们主要是在点击按钮时添加的功能。我们使用getSharedPreferences()方法来获得SharedPreferences实例,这个方法需要两个参数:第一个是用于指定SharedPreferences文件的名称(如果不存在则会自动创建一个);第二个参数是存储的模式,目前android中只有MODE_PRIVATE这一种模式。在使用edit()的方法活的Editor的实例后,我们就开始添加数据了,添加数据时需要两个参数:键值和数据。最后就是使用apply()方法来提交数据了。

    运行程序,点击按钮就可以成功存储数据,我们同样可以用Android Device Monitor来进行查看。

    2.读取数据

    SharedPreferences读取数据也是十分的简单,就是对SharedPreferences实例使用get...()方法来得到数据。

    继续使用上面的项目,再添加一个按钮,然后修改主代码:

    package com.example.yzbkaka.sharedpreferencestest;
    
    import android.content.SharedPreferences;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    
    public class MainActivity extends AppCompatActivity {
        Button save;
        Button restore;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            save = (Button)findViewById(R.id.button1);
            restore = (Button)findViewById(R.id.button2);
            
            save.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    SharedPreferences.Editor editor = getSharedPreferences("data",MODE_PRIVATE).edit();
                    editor.putString("name","yzbkaka");
                    editor.putInt("age",19);
                    editor.putBoolean("married",false);
                    editor.apply();
                }
            });
            restore.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    SharedPreferences pref = getSharedPreferences("data",MODE_PRIVATE);  //得到实例
                    pref.getString("name","");  //开始获取数据
                    pref.getInt("age",0);
                    pref.getBoolean("married",false);
                }
            });
        }
    }
    

    我们在第二个按钮的点击事件中添加操作,当我们点击时就会来获取数据。先还是使用getSharedPreferences()方法来得到SharedPreferences实例,然后就是使用get...()方法了,这个方法需要两个参数:第一个是键值,就是我们之前定义好的;第二个是默认值,即如果系统没有找到相应的键值,就会使用这默认值。

    SQLite数据库存储

    1.SQLite简介

    SQLite是一款轻量级的关系型数据库,它的运算速度特别快,而占用的资源很少,通常是只需要几百KB。而Android系统就是内置了这样一款数据库来让我们对大量的数据进行操作,它提供了一个SQLiteOpenHelper()的帮助型的抽象类,借助这个类我们就可以来对数据库进行创建和升级了。

    2.创建数据库

    首先还是创建一个空项目,然后为这个项目添加一个按钮,接着新建一个MyDatabaseHelper类,然后修改代码:

    package com.example.yzbkaka.databasetest;
    
    import android.content.Context;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteOpenHelper;
    import android.widget.Toast;
    
    
    public class MyDatabaseHelper extends SQLiteOpenHelper {
        public static final String CREATE_BOOK = "create table book("   //建表
                + "id integer primary key autoincrement,"
                + "author text,"
                + "price real,"
                + "pages integer,"
                + "name text)";
        Context mContext;
        
        public MyDatabaseHelper(Context context,String name,SQLiteDatabase.CursorFactory factory,int version){  // 构造函数
            super(context,name,factory,version);
            mContext = context;
        }
        
        @Override
        public void onCreate(SQLiteDatabase sqLiteDatabase) {  //重写的方法
            sqLiteDatabase.execSQL(CREATE_BOOK);
            Toast.makeText(mContext, "create successfully", Toast.LENGTH_SHORT).show();
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {  //重写的方法
    
        }
    }
    

    由于SQLiteOpenHelper是一个抽象类,所以我们需要自己建立一个类来继承它。我们先是创建了一个叫做CREATE_BOOK的数据库表,其中包含的信息包括书的价格、作者以及书的页数。然后就是来重写SQLiteOpenHelper中的方法,首先是构造函数,他一般包括四个参数:第一个参数就是Context;第二个参数是数据库的名称;第三个参数是一个自定义的Cursor,一般传入null即可;第四个参数是数据库的版本号。然后就是重写onCreate()和onUpgrade()方法,我们在onCreate()的方法中使用了execSQL()方法执行了建表的语句,然后发出一段短消息提醒建立成功。

    接着我们修改主代码:

    package com.example.yzbkaka.databasetest;
    
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    
    public class MainActivity extends AppCompatActivity {
        Button create;
        MyDatabaseHelper dbHelper;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            create = (Button)findViewById(R.id.create_database);
            dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,1);
            create.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    dbHelper.getWritableDatabase();
                }
            });
        }
    }
    

    我们在获得了MyDatabaseHelper对象之后,在按钮的点击方法里面我们使用了getWritable Database()方法来对数据库进行操作,这个方法可以创建或者打开一个现有的数据库(如果有数据库则直接打开,如果没有则会创建一个),在这里它发现没有这个数据库,因此它就会调用onCreate()方法来进行创建。

    如果我们想要修改数据库,例如再添加一张表到BookStore.db中,那我们就可以使用onUpgrade()方法来对数据库进行升级。我们修改MyDatabaseHelper类中的代码:

    package com.example.yzbkaka.databasetest;
    
    import android.content.Context;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteOpenHelper;
    import android.widget.Toast;
    
    
    public class MyDatabaseHelper extends SQLiteOpenHelper {
        public static final String CREATE_BOOK = "create table Book("
                + "id integer primary key autoincrement,"
                + "author text,"
                + "price real,"
                + "pages integer,"
                + "name text)";
    
        public  static final String CREATE_CATEGORY = "create table Category("
                + "id integer primary key autoincrement"
                + "category_name text"
                + "category_code integer)";
    
        Context mContext;
    
        public MyDatabaseHelper(Context context,String name,SQLiteDatabase.CursorFactory factory,int version){
            super(context,name,factory,version);
            mContext = context;
        }
    
        @Override
        public void onCreate(SQLiteDatabase sqLiteDatabase) {
            sqLiteDatabase.execSQL(CREATE_BOOK);
            sqLiteDatabase.execSQL(CREATE_CATEGORY);
            Toast.makeText(mContext, "create successfully", Toast.LENGTH_SHORT).show();
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
            sqLiteDatabase.execSQL("drop table if exists Book");
            sqLiteDatabase.execSQL("drop table if exists Category");
            onCreate(sqLiteDatabase);
        }
    }
    

    我们有新建了一个Category的表,然后在onUpgrade()方法中进行更新。更新的代码的含义是当数据库中存在叫做Book和Category的表时,就将该表删除,然后是调用onCreate()方法重新建表。这里要注意,如果我们更新了数据库,则必须要在主代码中的MyDatabaseHelp er的构造函数中修改版本号,否则onUpgrade()方法是无法执行的。

    package com.example.yzbkaka.databasetest;
    
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    
    public class MainActivity extends AppCompatActivity {
        Button create;
        MyDatabaseHelper dbHelper;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            create = (Button)findViewById(R.id.create_database);
            dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,2);  //修改版本号
            create.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    dbHelper.getWritableDatabase();
                }
            });
        }
    }
    

    执行程序,我们就可以更新数据库了。如果我们想要查看自己建立的数据库,可以使用AS中的adb shell工具来进行检查。

    3.SQLite中CRUD操作

    CRUD即:添加Create、查询Retrieve、更新Update和删除Delete。这是数据库操作中的四种最基本的操作,但是在Android中即使不使用SQL语句也可以实现这些操作,因为Android已经内置了这些操作的方法了。所以我们就来看一看吧。

    先在之前布局中添加4个按钮,分别叫做:C、R、U和D。

    1.添加数据Create

    在之前我们使用getWritableDatabase()方法时会返回一个SQLiteDatabase对象,我们就可以对该对象进行添加数据的操作,修改主代码:

    ......
    Button create = (Button)findViewById(R.id.create);
            create.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    SQLiteDatabase db = dbHelper.getReadableDatabase();  //获得SQLiteDatabase实例
                    ContentValues values = new ContentValues();   //获得ContentValues实例
                    values.put("name","book 1");  //开始存放数据
                    values.put("author","author 1");
                    values.put("pages",233);
                    values.put("prices",23.3);
                    db.insert("Book",null,values);  //添加数据1
                    values.clear();
                    values.put("name","book 2");
                    values.put("author","author 2");
                    values.put("pages",500);
                    values.put("prices",58.8);
                    db.insert("Book",null,values);  //添加数据2
                }
            });
    

    我们先是使用getReadableDatabase()方法获得了一个SQLiteDatabase的实例,然后是创建了ContentValues的对象来进行存放数据,存放数据时是使用put()方法,它需要的两个参数是:表中的列名和要添加的数据。之后就是使用SQLiteDatabase中的insert()方法,它需要三个参数:第一个是被添加数据的表名‘’第二个是自动赋值,一般是null;第三个是将values传入进行。然后我们使用clear()方法将values清空之后再次添加数据。

    2.查询数据Retrieve

    查询是SQL语句中最为重要的一项操作,因此它相比于其他的操作也是更为复杂一些。它使用的是SQLiteDatabase中的query()方法来进行查询操作。这个方法最常用的重载是要传入7个参数,具体的参数如下表:


    参数表

    不过参数虽然多,但是大多是情况下我们其实不用为每一条参数都设定值,而是直接传入null即可。

    我们接着使用上面的项目,对按钮R添加点击代码:

    ......
       Button retrieve = (Button)findViewById(R.id.retrieve);
            retrieve.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    SQLiteDatabase db = dbHelper.getWritableDatabase();
                    Cursor cursor = db.query("Book",null,null,null,null,null,null,null);
                    if(cursor.moveToFirst()){
                        do{
                            String name = cursor.getString(cursor.getColumnIndex("name"));
                            String author = cursor.getString(cursor.getColumnIndex("author"));
                            int pages = cursor.getInt(cursor.getColumnIndex("pages"));
                            double prices = cursor.getDouble(cursor.getColumnIndex("prices"));
                        }while(cursor.moveToNext());
                    }
                }
            });
    

    在使用查询操作的时候方法query()会返回一个Cursor的对象,我们就是利用Cursor来进行获取数据查询的操作的。在这里使用query()方法时我们只指定了第一个参数,即要查询的表的名字,而后面的参数都是传入null,表示我们不限定任何的查询条件。接着就是对Cursor实例使用get...()方法来得到数据。然后我们是使用了一个循环,可以让查询对表中的每一行都能够遍历到。

    3.更新Update

    更新使用的是SQLiteDatabase类当中的update()方法,该方法需要传入四个参数:第一个参数是表名;第二个参数是ContentValues对象;第三个是用于约束的条件;第四个则是对第三个的条件的一个补充。

    在按钮U中添加代码:

    ......
    Button update = (Button)findViewById(R.id.update);
            update.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    SQLiteDatabase db = dbHelper.getWritableDatabase();
                    ContentValues values = new ContentValues();
                    values.put("prices",26.6);
                    db.update("Book",values,"name = ?",new String[]{"Book 1"});
                }
            });
    

    这里面的大部分代码都很容易,我们直接看到最后的update()方法,在这个方法中前两个比较好理解,第三个参数的意思是修改的属性,这里指定的是name,然后使用?作为占位符,第四个参数则是对第三个补充,将它们结合起来看就是更新Book 1中的name项。

    4.删除数据Delete

    删除数据使用的方法是delete()方法,它只需要传入三个参数:第一个是要删除数据的表名;第二个是指定要删除数据所在的行;第三个就是对第二个的具体补充。

    修改按钮D中的代码:

    ......
      Button update = (Button)findViewById(R.id.update);
            update.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    SQLiteDatabase db = dbHelper.getWritableDatabase();
                    ContentValues values = new ContentValues();
                    values.put("prices",26.6);
                    db.update("Book",values,"name = ?",new String[]{"Book 1"});
                }
            });
    
            Button delete = (Button)findViewById(R.id.delete);
            delete.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    SQLiteDatabase db = dbHelper.getWritableDatabase();
                    db.delete("Book","pages>?",new String[]{"300"});
                }
            });
    

    很简单的代码,这里就不多解释了,嘿嘿。

    相关文章

      网友评论

        本文标题:Android入门(8)| 数据存储

        本文链接:https://www.haomeiwen.com/subject/amjsdqtx.html