Android中针对数据的持久化存储主要提供了3种:文件存储SharedPreference存储SQLite数据库存储。除了上面3种外,也可也将数据保存在设备的SD卡中,不过使用这3种相对更简单易用。

文件存储

Android中对文件存储的内容不进行任何格式化处理,所有的数据都是原样保存至文件中,因此比较适合存储一些文本内容或二进制数据。
存储的文件默认都是存储在路径:/data/data/{package_name}/files这个目录下,{package_name}为程序的包名。

将数据保存至文件

Context类中提供openFileOutput()方法,获取向文件写入数据的输出流。方法需要2个参数:第一个参数是文件名;第二个参数是写入模式,主要有2种(MODE_PRIVATEMODE_APPEND)。
MODE_PRIVATE:是默认的写入模式,该模式下,如果存在同名的时候,会将写入的内容完全覆盖源文件的内容。
MODE_APPEND:如果已存在该文件,就往该文件追加写入数据;如果文件不存在,则新建该文件。

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

从文件中读取数据

Context类中提供openFileInput()方法,获取从文件读取数据的输入流。

    private String load() {
        FileInputStream in = null;
        BufferedReader reader = null;
        StringBuilder sbd = new StringBuilder();
        try {
            in = openFileInput("data");
            reader = new BufferedReader(new InputStreamReader(in));
            String line = "";
            while (null != (line = reader.readLine())) {
                sbd.append(line);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(null != reader) {
                    reader.close();
                }
                if(null != in) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return sbd.toString();
    }

SharedPreferences存储

SharedPreferences存储是使用键值对的方式来存储数据。

获取SharedPreferences类

Android中主要提供了3中获取SharedPreferences对应的方式:

  • Context类中getSharedPreferences()方法。
    getSharedPreferences()方法接收2个参数,第一个参数指定文件名称,第二个参数指定操作模式。目前只支持支MODE_PRIVATESharedPreferences文件都是存放在/data/data/{package_name}/shared_prefs目录下。
  • ActivitygetSharedPreferences()方法。
    与上面的获取方法类似,不过只接收一个操作模式参数。该方式会自动将当前Activity类名作为SharedPreferences的文件名。
  • PreferenceManager类中的静态方法getDefaultSharedPreferences()
    getDefaultSharedPreferences()接收一个Context参数,并自动使用当前程序的包名作为前缀来命名SharedPreferences文件。

使用SharedPreferences存储数据

使用SharedPreferences存储数据主要可以分3个步骤:

  1. 通过SharedPreferences对象的edit()方法获取SharedPreferences.Editor对象;
  2. SharedPreferences.Editor对象中添加数据。如:editor.putStringeditor.putInteditor.putBoolean等;
  3. 调用SharedPreferences.Editor对象的apply()方法,完成数据存储。
SharedPreferences.Editor editor = getSharedPreferences("data", MODE_PRIVATE).edit();
editor.putString("name", "Tom");
editor.putInt("age", 20);
editor.putBoolean("flag", true);
editor.apply();

从SharedPreferences读取数据

SharedPreferences中读取数据,需要先获取SharedPreferences对象,然后调用一系列get()方法来获取不同类型的数据。get()接收2个参数,第一个参数是键值,第二个参数是默认值。

SharedPreferences pref = getSharedPreferences("data", MODE_PRIVATE);
String name = pref.getString("name", "");
int age = pref.getInt("age", 0);
boolean tb = pref.getBoolean("tb", false);

SQLite数据库存储

SQLite是一款轻量级关系型数据库,运行速度快并且占用资源少,支持标准SQL语法和数据库的ACID事务管理。上面的文件存储、SharedPreferences存储对于简单的数据存储很方便,拿来即用,但是需要存储大量的关系数据,就力不从心,这种情况使用SQLite就再好不过了。

SQLiteOpenHelper帮助类

为了更方便操作SQLite,Android专门提供了辅助类SQLiteOpenHelper。通过SQLiteOpenHelper可以非常方便的对数据进行创建和更新升级。

SQLiteOpenHelper抽象类提供了2个抽象方法:onCreate()onUpgrade()onCreate():用于创建数据库;onUpgrade():用于更新升级数据库。

SQLiteOpenHelper中另外还有2个非常重要的方法:getWritableDatabase()getReadableDatabase()。2个方法都能创建或打开数据库,即如果数据库不存在则进行创建并打开,返回一个可对数据库读写操作的对象。区别是,当数据库不可以写入时,getReadableDatabase()返回的对象将以只读方式打开数据库,getWritableDatabase()则会抛异常。
见代码:

public class MySQLiteOpenHelper 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,"
            + " `name` TEXT,"
            + " `code` INTEGER)";
    private Context mContext;

    public MySQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
        mContext = context;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_BOOK);
        db.execSQL(CREATE_CATEGORY);
        Toast.makeText(mContext, "Tables Create Success!", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("drop table if exists book");
        db.execSQL("drop table if exists category");
        onCreate(db);
    }
}

使用SQLite对数据机型增删改查

通过SQLite辅助类提供的API实现增删改查:

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";
    private MySQLiteOpenHelper dbHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // SQLite辅助类对象
        dbHelper = new MySQLiteOpenHelper(this, "book.db", null, 1);

        /*
         * 打开数据库
         */
        Button createDatabase = (Button)findViewById(R.id.create_database);
        createDatabase.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dbHelper.getWritableDatabase();
            }
        });

        /*
         * insert 添加数据
         */
        Button addData = (Button)findViewById(R.id.add_data);
        addData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SQLiteDatabase db = dbHelper.getWritableDatabase();
                ContentValues values = new ContentValues();
                for(int i = 1; i <= 100; i ++) {
                    values.put("author", "Author" + i);
                    values.put("price", 79);
                    values.put("pages", 588);
                    values.put("name", "Name" + i);

                    db.insert("book", null, values);
                    values.clear();
                }

                Toast.makeText(MainActivity.this, "AddData Success", Toast.LENGTH_LONG).show();
            }
        });

        /*
         * update 更新数据
         */
        Button updateData = (Button) findViewById(R.id.update_data);
        updateData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SQLiteDatabase db = dbHelper.getWritableDatabase();
                ContentValues values = new ContentValues();
                values.put("price", 80);
                values.put("pages", 199);
                values.put("name", "nnnnnnnnnnn");
                db.update("book", values, "id = ?", new String[] {"1"});
                Toast.makeText(MainActivity.this, "UpdateData Success", Toast.LENGTH_LONG).show();
            }
        });

        /*
         * delete 删除数据
         */
        Button deleteData = (Button) findViewById(R.id.delete_data);
        deleteData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SQLiteDatabase db = dbHelper.getWritableDatabase();
                db.delete("book", "id > ?", new String[]{"10"});

                Toast.makeText(MainActivity.this, "DeleteData Success", Toast.LENGTH_LONG).show();
            }
        });

        /*
         * query 查询数据
         */
        Button queryData = (Button)findViewById(R.id.query_data);
        queryData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SQLiteDatabase db = dbHelper.getWritableDatabase();
                Cursor cursor = db.query("book", null, null, null, null, null, null);
                if(cursor.moveToFirst()) {
                    do {
                        String author = cursor.getString(cursor.getColumnIndex("author")),
                            name = cursor.getString(cursor.getColumnIndex("name"));
                        int id = cursor.getInt(cursor.getColumnIndex("id")),
                                pages = cursor.getInt(cursor.getColumnIndex("pages"));
                        double price = cursor.getDouble(cursor.getColumnIndex("price"));
                        Log.d(TAG, "Id:" + id + "_author:" + author + "_price:" + price + "_pages:" + pages + "_name:" + name);
                    } while (cursor.moveToNext());
                }
                cursor.close();
            }
        });
    }
}

处理使用辅助类的API实现对数据库的增删改查外,该辅助类也支持直接使用SQL语句来操作数据库,主要使用:execSQL()来实现增、删、改操作;rawQuery()来实现查操作。

  • 添加数据

    db.execSQL("insert into book (`name`, `author`, `pages`, `price`) values (?, ?, ?, ?)", new String [] {"name1", "author1", "800", "132.88"});
  • 更新数据

    db.execSQL("update book set `price` = ? where id = ?", new String [] {"99.99", "1"});
  • 删除数据

    db.execSQL("delete from `book` where pages > ?", new String [] {"500"});
  • 查询数据

    db.rawQuery("select * from book where id > ?", new String [] {"10"});

使用LitePal操作数据库

LitePal是Android上的一款ORM数据库框架。具体可参看项目地址:LitePal

标签: android

添加新评论