Android入门(8)| 数据存储

12070003-6b74cd79f1f4c1e3.png
本节目录

文件存储

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

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个参数,具体的参数如下表:


12070003-9f44206ea8060892.png
参数表

不过参数虽然多,但是大多是情况下我们其实不用为每一条参数都设定值,而是直接传入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"});
            }
        });

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

猜你喜欢

转载自blog.csdn.net/weixin_34221773/article/details/87554282